C # basics: How to differentiate Dispose (), Close (), and Finalize ()

Source: Internet
Author: User
Tags gc collect reflector variable scope

. Net memory recycling and Dispose, Close, Finalize Methods
I. net objects are generally used in three situations ﹕
1. Create an object
2. Objects used
3. Release objects
2. Create an object
1. There are two steps to create an object: variable type declaration and initialization object
2. Variable type declaration (declare), such ﹕

Copy codeThe Code is as follows: FileStream fs

This line of code will create a variable named fs in the current variable scope space (stack or heap), at least four bytes (because the address of an object needs to be saved)
3. initialize the object
Objects must be initialized before they are used (calling their methods or attributes.
For example ﹕Copy codeThe Code is as follows: fs = new FileStream (@ "C: \ test.txt", FileMode. OpenOrCreate );

This line of code is divided into three steps ﹕
A. Allocate a piece of memory in the managed heap. The size is equal to the total memory size of all fields in FileStream (excluding static ones, of course) and other things that MS considers necessary.
B. initialize the fields of the object (Initialize all its bits of the value type to 0, and initialize the object to null. Of course, string is an exception and is initialized to a null string)
C. Call the corresponding constructor of FileStream. A private field of the unmanaged Resource (File) is initialized here.
Iii. Objects used
There is nothing to say about using objects, that is, calling methods (or attributes) of objects) of course, methods called to release objects should not belong to this category (Finalize, etc)
4. Release objects
1. releasing an object is unnecessary. Now I want to release it so that the memory space occupied by the object on the stack can be reclaimed (of course, the memory space of the variable name is not needed ). because it will automatically disappear with its scope)
2 .. net Automatic memory management, that is, when it judges an object is useless (of course, it has its own algorithm) it will automatically reclaim its memory, but its recovery time is generally unknown (when. net will start when the memory is insufficient)
BTW: in fact, it is impossible for us to reclaim the object's memory, because MS does not provide a way (GC. Collect is also used to start the. net memory collection function)
V. first conclusion
Using an object in net is simple. You can use it directly after creating an object. You don't have to worry about it anymore. The Garbage Collector will help you get the memory back.
6. Exceptions
When an object member references an unmanaged Resource (memory or resources not allocated on the managed stack, such as files, database connections, etc.), the following example is used ﹕
System. IO. FileStream class, which is an unmanaged Resource (File) Encapsulation object provided by the. net basic class library (the mscorlib. dll code can be decompiled using the Reflector tool)
1. FileStream undoubtedly encapsulates an unmanaged Resource
Looking at its source code, we found such a private member ﹕Copy codeThe Code is as follows: private SafeFileHandle _ handle;

Through the Init method called by the constructor, we can find the initialization code of this Member ﹕Copy codeThe Code is as follows: this. _ handle = Win32Native. SafeCreateFile (text2, num1, share, secAttrs, mode, num2,
Win32Native. NULL );

The latter is actually the CreateFile method in kernel32.dll, which returns a HANDLE (that is, an unmanaged resource reference)
2. Use this category first ﹕Copy codeThe Code is as follows: using System;
Using System. IO;
Public class TestFileStream
{
Public static void Main (string [] args)
{
// Create a FileStream object
FileStream fs = new FileStream (@ "C: \ test.txt", FileMode. OpenOrCreate );
Console. WriteLine ("You can try to delete test.txt under drive C in the system (enter key to continue )");
// Pause the program execution and try to delete the file in the system
Console. ReadLine ();

// Delete file test
Try
{
File. Delete (@ "c: \ test.txt ");
}
Catch (IOException ex)
{
Console. WriteLine ("[Error] failed to delete the file: {0}", ex. Message );
}
}
}

3. when the program is suspended (Console. readLine waiting for input) deleting a file fails and is easy to understand. Because the file is not closed after it is opened, the system does not know whether the file is still useful, so it helps us protect the file (of course, the unmanaged Resource the memory used is also occupied by the Program)
4. But after the program is executed, we try to delete the file again? (Does fs not close the SafeFileHandle ?)
Of course, you can say that the windows operating system will automatically recycle its resources after a process is completed (but if it is com, it will be miserable because com exists in its own independent process, and the operating system is not responsible for this :() however, this is not because of the features of the windows operating system. net garbage collector.
5. Let's look at the example below.Copy codeThe Code is as follows: using System;
Using System. IO;
Public class TestFileStream
{
Public static void Main (string [] args)
{
// Create a FileStream object
FileStream fs = new FileStream (@ "C: \ test.txt", FileMode. OpenOrCreate );
Console. WriteLine ("You can try to delete test.txt under drive C in the system (enter key to continue )");
// Pause the program execution and try to delete the file in the system
Console. ReadLine ();

/** // * Collect garbage */
GC. Collect ();
Console. WriteLine ("try again ");
Console. ReadLine ();
}
}

6. Pay attention to the line of code in the middle:Copy codeThe Code is as follows: GC. Collect ();

This is to force the. net Garbage Collector to collect garbage.
Let's try to delete test.txt again. Why? (Does fs not close the SafeFileHandle ?) Let me explain in detail ﹕
7. First, let's take a look at the four opportunities for the. net Garbage Collector to collect garbage (see the. net Framework Program Design translated by Li Jianzhong)
A. Most common: When. net feels appropriate, for example, it feels memory tight (the alias is: The 0-generation object is full)
B. It is strongly not recommended by Microsoft: GC Collect method call (this is the one we used above, because it will reduce the performance and suspend the process, etc. Listen to Microsoft anyway. Of course, it can be used in some cases, just like the code I used for testing, huh ...)
C. AppDomain)
D. When CLR is disabled
8. now we can understand why the file can be deleted after the program ends in 1st examples, because when the CLR is disabled ﹐.. net, which is equivalent to the GC in the second example. collect () code)
9. So now all the problems are concentrated on garbage collection. What does it do?
A. the Garbage Collector starts to collect garbage from an object after it judges that it will not be referenced again (that is, reclaim the memory)
B. Clear the memory (that is, reclaim the memory in the managed heap)
C. What should I do if some fields of an object reference an unmanaged resource? For example, FileStream's _ handle
D. therefore, we must tell the Garbage Collector that before you recycle my memory, you can first help me to execute a method to reclaim my unmanaged resources, so as to avoid the memory of the managed heap being recycled by you, and I the memory of the referenced unmanaged resource is leaked.
E. This method is Finalize (), that is, C ~ ClassName () method (same as the Destructor syntax in C ++)
F. If an object has a Finalize method, the garbage collector will automatically call this method before it recovers its memory.
G. In this way, we can clean up those (unmanaged resources ).
From this point of view, the mechanism provided by the garbage collector is to better improve the. net automatic memory management function, so that we can also participate in the garbage collection.
10. Let's take a look at what GC. Collect () does. Net do when this line of code or CLR is disabled ﹕
A. When the garbage collector is started, it is found that the object referenced by fs is useless. (Of course, You can recycle the object when the CLR is disabled .)
B. We found that the fs type: FileStream provides the Finalize method, so we call this method first.
(Reflector continues as follows)
C. The Finalize method contains the this. _ handle. Dispose () code, so SafeHandler. Dispose () is called ()
D. Go to (of course, there are many circles for you to take a long time...) SafeFileHandle. ReleaseHandle method and find the code: Win32Native. CloseHandle () (that is, close the unmanaged resource-file HANDLE)
The truth is: the Garbage Collector helped us shut down the unmanaged Resource (of course, we still wrote the Finalize method), so we can delete the file later.
11. Some people may ask: It seems that we are not so complicated when using FileStream objects?
A: Very Good!
The reason is that the test.txt file under the C drive has been very helpful to everyone and I have been using it since it was created. since it was created, I have never used it any more. check whether this part of the resource has been leaked, has it been locked, and at the end of the program, has been helped ﹐ the HANDLE of the file that you forgot to close is returned.
Others: A "dumb bullet" is buried in the program, so I don't know when it will pop up. Just like the File. Delete method in my example, an exception occurs.
(But I think) The vast majority of people are reading a lot. net programming advice, Microsoft strongly recommends, MSDN standard practices, and so on (and my blog, haha). After knowing that when using FileStream or SqlConnection, you must Close it.
12. Close and Dispose
The code for the two examples is not standard. The correct method should be to call fs. Close () to Close the FileStream after it is used to ensure resource security.
Appendix: correct practices
Copy codeThe Code is as follows: using System;
Using System. IO;
Public class TestFileStream
{
Public static void Main (string [] args)
{
// Create a FileStream object
FileStream fs = new FileStream (@ "C: \ test.txt", FileMode. OpenOrCreate );
/** // * Close after FileStream is used up */
Fs. Close ();

// Delete file test
Try
{
File. Delete (@ "c: \ test.txt ");
}
Catch (IOException ex)
{
Console. WriteLine ("[Error] failed to delete the file: {0}", ex. Message );
}
}
}

13. Someone raised his hand and told me so much about it that it would not be enough to call fs. Close.
Dude, fs. the Close () method is written by you. If you do not call the Close () method, if you do not call the Close () method, when a program is faulty, you may call it Microsoft spam ﹐. net is really unstable, or java is good, secure, reliable... MS has to add this item to the garbage collection to prevent unexpected attacks...
14. Dispose Mode
Carefully check the basic classes in the. net class library. All classes with Finalize Methods basically provide methods such as Dispose, Close, and Dispose (bool) (FileStream is no exception)
15. In fact, whether it is the Dispose, Close, and Finalize methods, the same code should be executed eventually.
Differences ﹕
Finalize method: can only be called by Microsoft
Dispose and Close Methods: provided for you to call
Therefore, after you use those categories, you can directly call Close (no Close, and then call the Dispose method) of course, if you forget it, don't worry. There are also garbage collectors to help you pad it.
VII. Second conclusion ﹕
1. When you develop a class that encapsulates unmanaged resources (that is, fields in the class reference to unmanaged resources ﹕
A: We strongly recommend that you use the Finalize method to release unmanaged resources. the. net garbage collector will not automatically recycle that part of the resources, but will call your Finalize method to release the resources. (This ensures that when the programmer of your class forgets to manually recycle the memory, it can also be remedied by the Garbage Collector)
B. It is strongly recommended that you provide a Close or Dispose method so that programmers in your category can manually release unmanaged resources in your category. (See the. net Framework Program Design Automatic Memory Management chapter to implement the Dispose mode)
C. if the category encapsulates objects such as FileStream (that is, re-encapsulation of unmanaged resources) generally, you should also provide a Close or Dispose method, unless your member is properly closed after each use, that is, transparent to the caller.
2. When you use a category that encapsulates unmanaged resources ﹕
A: We strongly recommend that you call the Close or Dispose method provided by Alibaba Cloud to manually release the memory of your unmanaged resources after you know that this category is useless. There is a saying: it is not difficult to borrow a loan. If you borrow a loan, you can borrow it again ~~
B: Do not call the related methods of this object after manual release, because the object has been damaged.
BTW again: no matter whether it is Finalize, Close or Dispose, you cannot explicitly release the managed heap memory. They will always be Microsoft's "private property "﹕)
Summary: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 is.
In. in the net framework, close () is designed to be public, and hidden dispose () is called in close (), and then dispose () calls another virtual dispose (bool)
Function. Therefore, if you inherit from this class, you must implement the dispose (bool) method. By using close (), the caller indirectly calls the overloaded dispose (bool) method to release the resource.
Because close () is only used to call the hidden dispose () and then call dispose (bool), the user should not change the close Behavior
Classes with the disponse () method implement the IDisposable interface. In. net, many classes only provide close (), instead of disponse (), but it does implement the idisponse interface,
Why?
The reason is that the interface implementation mode-explicit implementation of implicit implementation, the difference between the two: For implicit implementation, you only need to call "new ClassA (). dispose () ", but for explicit implementation
For example, dispose () is not a member function of the classA. The only call method is to forcibly convert the type to IDisposable, that is, "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.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.