C basics: the differences between Dispose of Close of Finalize of

  • 2020-05-12 03:13:27
  • OfStack

.net memory recovery with Dispose and Close and Finalize methods
1. The objects of net can be divided into three types by 1
1. Create objects
2. Use objects
Release the object
2. Create objects
1. Creating an object is actually divided into two steps: declaring the type of the variable and initializing the object
2. Variable type declarations (declare), such as the wat


FileStream fs

This line of code will create at least 4 bytes of a variable called fs in the current variable scope space (stack or heap).
3. Initialize the object
An object must be initialized before it can be used (by calling its methods or properties).
Such as �

fs = new FileStream(@"C:\test.txt",FileMode.OpenOrCreate);

This line of code is divided into three steps
a. Allocate 1 block of memory in the managed heap, the size of which is equal to the sum of all the fields in FileStream (not static, of course) plus whatever else MS thinks it needs.
Initialize the fields of an object (value type initializes all bits to 0, object is initialized to null and string is of course an exception and it is initialized to an empty string)
c. Calling FileStream's corresponding constructor initializes the private field of an unmanaged resource (file).
3. Use objects
There is nothing to be said about using objects except calling methods (or properties, etc.) of an object to perform a function and of course calling methods to release objects should not fall into this category (Finalize, etc.)
4. Release the object
1. Free the object means that I no longer need the inside of the object. Now I need to free the inside of the object so that I can retrieve the memory space it occupies on the heap. (of course, I don't need to control the inside of the variable name because it will disappear with its scope.)
2. net automatically manages the memory. This means that when it determines that an object is no longer useful (it has its own algorithm, of course), it automatically retrieves the memory from the object, but it does so at an uncertain time (it starts when net believes that memory is tight).
BTW: in fact, we can not recover the memory of the object even if we want to, because MS does not provide a way (GC.Collect is also enabled.net's memory collection function).
5. Conclusion 1
It's easy to use objects in net and just use them when you create them and don't use them anymore and don't worry about them and the garbage collector will get the memory back for you.
6. Exception
When a member of an object references an unmanaged resource (memory not allocated on the managed heap or a resource like a file, a database connection, etc.), the following example illustrates a pool
System.IO.FileStream class. This is an unmanaged resource (file) wrapper object provided by the.net base class library (see the code for mscorlib.dll by decomcompiling mscorlib.dll with the Reflector tool).
1.FileStream undoubtedly encapsulates an unmanaged resource
View its source code found that there is such a private member

private SafeFileHandle _handle;

The Init method called by the constructor can be used to discover the initialization code of this member

this._handle = Win32Native.SafeCreateFile(text2, num1, share, secAttrs, mode, num2,  
Win32Native.NULL);

The latter is actually the CreateFile method in kernel32.dll and it returns an HANDLE(that is, an unmanaged resource reference)
2. Let's use this category first

using System;
using System.IO;
public class TestFileStream
{
    public static void Main(string[] args)
    {    
           // create 1 a FileStream object 
        FileStream fs = new FileStream(@"C:\test.txt",FileMode.OpenOrCreate);        
        Console.WriteLine(" You can try to delete from the system c Under the plate test.txt( Enter to continue )");
        // Pause the program to execute and try to delete the file from the system 
        Console.ReadLine();
        // Delete file test 
        try
        {
            File.Delete(@"c:\test.txt");
        }
        catch (IOException ex)
        {
            Console.WriteLine("[Error] The program failed to delete the file {0}",ex.Message);
        }
    }
}

It is easy to understand when a file is not closed when it is opened. The system does not know if the file is still in use, so it helps us to protect the file (of course, the memory used by the unmanaged resource is still being used by the program).
4. But after the program is finished, we will try to delete the file. (didn't fs turn off the SafeFileHandle?)
Of course, you can say that the windows operating system automatically retrievesthem after a process has finished. That's true (but if it's com, it's bad because com exists in its own separate process and the operating system is not responsible for them :() but it's not because the windows operating system does the trick, it's because the net garbage collector does the trick.
Take a look at the following example

using System;
using System.IO;
public class TestFileStream
{
    public static void Main(string[] args)
    {
        // create 1 a FileStream object 
        FileStream fs = new FileStream(@"C:\test.txt", FileMode.OpenOrCreate);
        Console.WriteLine(" You can try to delete from the system c Under the plate test.txt( Enter to continue )");
       // Pause the program to execute and try to delete the file from the system 
        Console.ReadLine();
        /**//* Garbage collection */
        GC.Collect();
        Console.WriteLine(" And then delete 1 The try ");
        Console.ReadLine();
    }
}

6. Notice the middle line of code:

GC.Collect();

This is mandatory for the.net garbage collector to do garbage collection.
We will try to delete test again. Why is it that the txt can be deleted? (didn't fs turn off the SafeFileHandle?) Let me talk about it
7. Let's start with a look at the four garbage collection opportunities in the.net garbage collector.
a. The most common example is when.net feels like it is running out of memory.
b. Microsoft strongly discourages the use of the Collect method calls to the wok 112en. (this is the one we used above because it can degrade performance. Of course, sometimes you can use it with code like the one I used to test above.
c. Application domain uninstall (AppDomain)
d.CLR is closed
8. Now we can see why in the first example the file can be deleted after the program is finished because when CLR is closed, the.net performs garbage collection (i.e., the GC.Collect () code equivalent to the second example)
9. So now all the questions focus on garbage collection and what does it do?
a. The garbage collector begins garbage collection on an object after it has determined that it will no longer be referenced.
b. Empty memory (that is, reclaim memory from the managed heap)
c. But what if some of the fields of the object refer to an unmanaged resource? Such as FileStream _handle
d. So we have to tell the garbage collector to perform a method for me to retrieve my unmanaged resource before you reclaim my memory so that the managed heap memory is not reclaimed by you and the memory of the unmanaged resource I referenced is leaked.
e. This method is Finalize(), which is also C# 's ~ClassName() method (same as the destructor syntax in C++).
f. So if an object has an Finalize method, the garbage collector will automatically call this method before it can reclaim its memory
g. That way we can clean up those things (unmanaged resources)
Therefore, the mechanism provided by the garbage collector is for the better. The automatic memory management function of net allows us to participate in garbage collection
10. Let's look at the GC.Collect () line or when CLR is off. What does Net do
When the garbage collector starts the wok, it finds that the object referenced by fs is no longer useful (although when CLR is closed, it doesn't matter if you have used the wok or not). The wok then recycles it
b. Discovers that the type of fs, the FileStream, provides the Finalize method, and calls this method first
(continue below via Reflector)
The c.Finalize method has the this._handle.Dispose () code so it calls SafeHandler.Dispose ()
Then turn to (of course, take your time...) SafeFileHandle.ReleaseHandle method -- discovery code -- Win32Native.CloseHandle () (that is, close the unmanaged resource -- file HANDLE)
It turned out that the garbage collector had enabled us to close the unmanaged resource (again, through our own Finalize method) so that we could delete the file later.
11. Some people may ask if using FileStream objects is not so complicated.
A � Very Good!
1 some people � because everyone and good luck my case 11 samples � the test under C dish. txt file since it was created after � I won't go to use it at � mind this portion of the resources have been leaking � have locked � � at the end of the last program helped by the garbage collector � to forget to close the file HANDLE give back.
The remaining 1 person has planted a "dud" in the program and it will explode at some point, just like the File.Delete method in my example has an exception.
The vast majority of people have seen a lot of things like net programming advice, Microsoft strongly recommends standard practices like MSDN, etc. (and I have this blog video, too) and learned that when using things like FileStream,SqlConnection, the app must include Close.
12. Close Dispose
Check that the code in both of our examples is non-standard. The correct way to do this is to use fs.Close () to close the code after the FileStream has been used to secure the resource.
Correct practice is attached

using System;
using System.IO;
public class TestFileStream
{
    public static void Main(string[] args)
    {
        // create 1 a FileStream object 
        FileStream fs = new FileStream(@"C:\test.txt", FileMode.OpenOrCreate);
        /**//* After using FileStream After the closing */
        fs.Close();
        // Delete file test 
        try
        {
            File.Delete(@"c:\test.txt");
        }
        catch (IOException ex)
        {
            Console.WriteLine("[Error] The program failed to delete the file {0}", ex.Message);
        }
    }
}

13. If someone raises their hand and talks so much, please tell me to call fs.Close.
The fs. Close () method is created by you. If you don't want to call it, you can call it. If you don't want to call it, you can call it. In order to prevent abuse in your country, we have to add this one to the garbage collection in case of accidents...
14. Dispose mode
Take a closer look. The basic classes in the net class library provide methods such as Dispose,Close,Dispose(bool) in most cases where the Finalize method is available (FileStream is no exception)
15. Dispose,Close,Finalize should all end up executing the same code
The difference between �
The Finalize method can only be called by Microsoft
The Dispose and Close methods are provided for you to call
So when you're done with those categories, call Close directly (no Close and then call Dispose). Of course, if you forgot about the Close, don't worry about the garbage collector.
7. The second conclusion
1. When you develop a category that encapsulates an unmanaged resource (that is, a field in the class references an unmanaged resource)
A: it is strongly recommended that you provide the Finalize method to release the unmanaged resource. The net garbage collector does not automatically recycle the unmanaged resource by calling your Finalize method. (this ensures that if the programmer who is using your category forgets to recycle memory manually, the wok can also be retrieved by the garbage collector.)
B. It is strongly recommended that you provide an Close or Dispose method so that programmers using your category can manually release unmanaged resources in your category. (see.net framework programming automatic memory management 1 chapter to implement Dispose mode)
If the class encapsulates an object such as FileStream (i.e., re-encapsulation of an unmanaged resource), an Close or Dispose method should also be provided with an Close or Dispose method, unless your member guarantees that it will be properly closed after each use, which is transparent to the caller.
2. When you use a class that encapsulates an unmanaged resource
A: it is strongly recommended that you manually free the memory of its unmanaged resource by calling the Close or Dispose methods provided by the WMD when it is clear that this category is not useful. It is not difficult to borrow and to borrow again. If you don't return the loan, you can borrow it again
B: note that after manually releasing the wok, do not call the associated methods on this object again because the wok has been corrupted
Once again, BTW: you will not be able to explicitly free the managed heap from either Finalize or Dispose, which will always be Microsoft's "private property".
Conclusion: Dispose and Close are basically the same. Close is designed for developers who are not familiar with Dispose. Close makes it easier to understand what it does.
In.net framework, close() is designed to be public, and the hidden dispose() is called from close(), and dispose() calls another virtual dispose(bool)
Function. So if you inherit from this class, you have to implement the dispose(bool) method. Using close(), the caller will indirectly call the dispose(bool) method you overloaded to release the resource.
Since close() is only used to call the hidden dispose() and then to call dispose(bool), the user should not change close's behavior
The class with the disponse() method implements the IDisposable interface. A lot of class in net only provides close(), not disponse(), but it does implement the idisponse interface,
Why is that?
The reason is because of the implementation pattern of the interface -- explicit implementation of the implicit implementation -- and the difference between the two: for the implicit implementation, you only need to call "new ClassA().Dispose()", but for the explicit implementation
For example, dispose() would not be a member of classA. The only way to call 1 is to cast the type to IDisposable first, i.e. "new ClassA().Dispose()", but ((IDisposable)new ClassA()).Dispose() can be compiled. This meets the design requirements: provide close(), hide dispose(), and implement the IDisposeable interface


Related articles: