C # Memory recycling and Dispose, Close, Finalize method [convert] From: http://blog.csdn.net/xykwgjyygy/archive/2008/01/11/2037741.aspx
. 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 ﹕
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 ﹕
Fs = new FileStream (@ "C: est.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 ﹕
Private SafeFileHandle _ handle;
Through the Init method called by the constructor, we can find 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, which returns a HANDLE (that is, an unmanaged resource reference)
2. Use this category first ﹕
Using System;
Using System. IO;
Public class TestFileStream
...{
Public static void Main (string [] args)
...{
// Create a FileStream object
FileStream fs = new FileStream (@ "C: est.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: est.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.
Using System;
Using System. IO;
Public class TestFileStream
...{
Public static void Main (string [] args)
...{
// Create a FileStream object
FileStream fs = new FileStream (@ "C: est.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 ();
/** // * Collects garbage */
GC. Collect ();
Console. WriteLine ("try again ");
Console. ReadLine ();
}
}
6. Pay attention to the line of code in the middle: 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 ++)
The Destructor is added before the class name ~. No return value ., however, the calling mechanism of c # destructor is different from that of C ++. it cannot be guaranteed to be called every time. therefore, it is best not to use the C # destructor to recycle resources. the destructor in C # is meaningless because C # Is the system determines when the managed program will analyze the structure and execute garbage collection.
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
Using System;
Using System. IO;
Public class TestFileStream
...{
Public static void Main (string [] args)
...{
// Create a FileStream object
FileStream fs = new FileStream (@ "C: est.txt", FileMode. OpenOrCreate );
/** // * Close after FileStream is used up */
Fs. Close ();
// Delete file test
Try
...{
File. Delete (@ "c: est.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 "﹕)
Some people discuss:
. Net do not set the object to null;
A variable of. net, such
FileStream fs = new FileStream (@ "C: \ test.txt", FileMode. OpenOrCreate );
This fs is similar to a pointer in the c language, just an address.
= Null is useless.
If the value is null, gc collection is affected.
There are also. net Windows programs
It may be different from GC collection in ASP. NET.
Therefore, such a column does not completely explain the problem.
If the cpu usage is high, GC may be slow to recycle objects.
It is much slower than normal.
In principle, the Dispose class is required.
If a FileStream-like object is not used in subsequent code, you do not need to close it directly.
Dispose. Dispose implies close.
The using code block is also recommended for automatic release of data connection objects to prevent exceptions in the middle.