Using and Garbage Collection

2019-01-26 15:27发布

问题:

Hi just to clairfy if I have the following:

using (Object1) {
create Object2
}
// bookmark1

Will Object2 be destroyed at bookmark1 along with Object1? Object2 is of StringReader and Object1 is of MemoryStream.

回答1:

Neither object will be destroyed at the end of the block.

Object1 will be Disposed, a different concept; nothing will happen to Object2.

Both objects will be collected, and may be finalised, sometime later. Garbage collection is non-deterministic - you can't rely on when it will occur.

See IDisposable on MSDN for more.



回答2:

A using block is really syntactic sugar for a construct like this:

try
{
    Brush b = new SolidBrush(Color.Red);
}
finally
{
    b.Dispose();
}

So, 'b' will be disposed at the end of the try block unless something happens which is outside the control of the application.



回答3:

At the end of the block (bookmark1), in your example, only object 1 will be disposed. In the case of a file stream, this means that the stream will be closed and the handle will be released, but the actual string object will still be in memory (ready to be cleaned by the GC). In your case, Object2 will not be disposed, so the handle it uses will still be kept open. Eventually, the GC will collect it, and call its finalizer, at which time it will get released correctly.

If you want both objects to be "cleaned up" correctly, they both will need to be disposed, either via wrapping them in using statements, or calling Dispose manually.

There is the alternative, potentially cleaner syntax as well:

using (Object1 obj1 = new Object1(), Object2 obj2 = new Object2())
{
    // Do something with obj1 & obj2
}

If you do this, obj1 AND obj2 will both be Disposed at the end of the block. In your case, this means both objects will be closed, and their handles released. The GC will then clean them up at some future garbage collection.

For details, see MSDN's page on using.



回答4:

object2 will not be destroyed (disposed) with object1. However, a separate scope block is created for the using statement so object2 does go out of scope at this point. It's disposal is just not deterministic.

Also, if object2 is also an IDisposable you can do this:

using (object1)
using (object2)
{
} // bookmark1

No matter what, normal garbage collection rules apply: the managed resources (memory) for the object are still handled in the normal fashion. Using/IDisposable only releases un-managed resources.