Today to talk about the C # GC, garbage collection mechanism, very teachable, summarized as follows
First: Talk about hosting, what is managed, my understanding is to entrust the C # operating environment to help us to manage, in this operating environment can help us to open up memory and release memory, open memory generally with new, memory is randomly allocated, release is mainly by GC is garbage collection mechanism. There's two big questions. 1.GC can I recycle any object? 2.GC when will the object be recycled? Reclaim those objects?
For the first question, can a GC reclaim any object? I understand that, the first thing to understand, C # in the strong also can not control unmanaged code? What, what is unmanaged code? such as stream (file), connection (database connection), COM (component), etc... Where do these objects need to be connected, for example we write such a sentence FileStream fs = new FileStream ("D://a.txt", FileMode.Open); You have actually created a connection to d://a.txt, and if you repeat it two times you will get an error. What, FS? This object is called an unmanaged object, which means C #
Unable to automatically release and d://a.txt the connection. What, what about unmanaged code?
For the second question, when will the GC be recycled and what objects are recycled? I don't think I need to say the back, of course, the collection of managed objects. But when does the GC recycle? It's like this: The GC is random, no one knows when he's coming, and I wrote an example to prove it.
private void Button1_Click (object sender, EventArgs e)
{
AA a = new AA ();
AA B = new AA ();
AA C = new AA ();
AA d = new AA ();
}
public class aa{}
Before telling this example, to understand what is called garbage, Garbage is an area of memory that is not pointed to by any reference, or is no longer used. The first time you click on the button will generate 4 objects, the second click on the button will also generate 4 objects, but the first generation of 4 objects is already garbage, because the first generation of the 4 objects with the end of the Button1_Click function will not be called again ( Or can not be called again , which is this time the GC will be recycled? No! I said the GC is random, where you just point your, and the GC will come back ( here we can think that there is a certain amount of garbage in memory after the GC will come ), to prove that the GC has come to us to change the AA class to
public class AA
{
~AA ()
{
MessageBox. Show ("destructor is executed");
}
}
To understand that GC cleans up garbage, actually calls destructors, but the code is managed code (because it doesn't involve steam, Connection, etc.). So in the destructor, we can just write a MsgBox to prove the idea; this time, run your program, always click the button, there will be a lot of "destructor is executed" ...
OK, and then let's see if we can change the nature of the GC, the answer is yes, we could call Gc.collect (); To force GC for garbage collection, which button1_click modified as follows
private void Button1_Click (object sender, EventArgs e)
{
AA a = new AA ();
AA B = new AA ();
AA C = new AA ();
AA d = new AA ();
Gc. Collect ();
}
When you click the first button, generate four objects and then force the garbage collection, will it be recycled? Of course not, because, these four objects are still in the execution (the method is not finished), when the point of the second button, there will be four times "destructor is executed", this is the first click on the release of four objects, and then each click will appear four times "destructor is executed", The last time the object was released, it was released when the program was closed (because all memory was freed by closing the program).
OK, now to talk about unmanaged code, just said that unmanaged code can not be released by garbage collection, we changed the AA class to the following
public class AA
{
FileStream fs = new FileStream ("D://a.txt", FileMode. Open);
~AA ()
{
MessageBox. Show ("destructor is executed");
}
}
private void Button1_Click (object sender, EventArgs e)
{
AA a = new AA ();
}
If this is the case, the second click will be an error, because a file can only create a connection. Where is it? Be sure to release the first resource before you can make a second connection. What, first we think of GC. Collect (), to force the release of idle resources, modify the code as follows:
private void Button1_Click (object sender, EventArgs e)
{
Gc. Collect ();
AA a = new AA ();
}
Where can you see, the second point button, there is a "destructor is executed", but the program is still wrong, the reason I said earlier, because stream is not managed code, so C # can not help us to recycle, what to do?
Write your own Dispose method, and release our memory. The code is as follows:
public class Aa:idisposable
{
FileStream fs = new FileStream ("D://a.txt", FileMode. Open);
~AA ()
{
MessageBox. Show ("destructor is executed");
}
#region IDisposable Members
public void Dispose ()
{
Fs. Dispose ();
MessageBox. Show ("Dispose executed");
}
#endregion
}
OK, we see, inherit the IDisposable interface will have a Dispose method (of course, you do not want to inherit also can, but the interface gives us a rule, you do not want to abide by this rule, you can never fit into the whole team, your code only one person to understand), Okay, gossip doesn't say, so our button1_click is changed to private void Button1_Click (object sender, EventArgs e)
{
AA a = new AA ();
A.dispose ();
}
Each time we clicked, we found that "dispose executed" was executed, and the "destructor was executed" when the program was closed. This means that the GC is still working, and if the program changes to:
private void Button1_Click (object sender, EventArgs e)
{
AA a = new AA ();
A.dispose ();
Gc. Collect ();
}
Each time there is "Dispose executed and" "Destructor is executed", which means that the GC again to make trouble, which is like this contains the stream connection object, no GC to clean up, just need us to add the last Word GC. SuppressFinalize (this) tells the GC that it will not have to call the object's destructor again. then the rewritten AA's Dispose method is as follows:
public void Dispose ()
{
Fs. Dispose ();
MessageBox. Show ("Dispose executed");
Gc. SuppressFinalize (this);
}
C # GC garbage collection mechanism