Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does the "using" keyword mean the object is disposed and GC'ed?

I struck up a conversation with my colleague today, who said she'd just learned the reason behind using the using statement.

 //Using keyword is used to clean up resources that require disposal (IDisposable interface).    using (StreamReader reader = new StreamReader(@"C:\test.txt"))   {   string line = reader.ReadLine();   }  

I pointed out that the object is marked as "Can be disposed" but not actually disposed and garbage-collected unless GC decides to do so.

She responded that the object will be disposed automatically once that using statement ends because the using statement is translated to try-catch-finally block. So, the object must get disposed at the very end of the using statement.

I was confused by this, because I know that using a using statement does not guarantee that the object gets GC-collected. All that happens is that the Dispose() method would be called. The GC decides when to GC it regardless. But when she asked for proof, I could not find any.

Does anyone know how this works, and how to prove it?

like image 643
now he who must not be named. Avatar asked Apr 22 '14 07:04

now he who must not be named.


People also ask

Is Dispose called by GC?

The GC does not call Dispose , it calls your finalizer (which you should make call Dispose(false) ).

What is Dispose () and Finalize ()?

Finalize is the backstop method, called by the garbage collector when it reclaims an object. Dispose is the "deterministic cleanup" method, called by applications to release valuable native resources (window handles, database connections, etc.)

What is object Dispose?

In the context of C#, dispose is an object method invoked to execute code required for memory cleanup and release and reset unmanaged resources, such as file handles and database connections.


Video Answer


1 Answers

You're talking about two very different things.

The object will be disposed as soon as the using-block ends. That doesn't say anything about when it is garbage collected. The only time heap memory is released is when a garbage collection occurs - which only happens under memory pressure (unless you use GC.Collect explicitly).

Disposing an object simply means calling its Dispose method. That most often means releasing either a scarce resource, or a native resource (in practice, all scarce resources are native - sockets, files, ...). Now, it's handy that the lifetime of the disposable object in your case is limited in scope, so it could theoretically be collected as soon as the using-block ends - however, that doesn't really happen in practice, since the .NET runtime tries to avoid collections - they're expensive. So until you cross a memory allocation threshold, no collection is going to happen, even though you have a dead object on the heap.

So what's the point of Dispose? Nothing to do with managed memory. You don't really care about managed memory, and you shouldn't expect that Dispose will actually be called - it doesn't have to be. The only thing that has to be called by the runtime is the finalizer, and you can only ever use that for disposing of native resources - in fact, there's no guarantee if the objects you have a reference to still exist by the time the finalizer runs - the managed memory might have already been reclaimed by then. That's why you never handle managed resources in a finalizer.

So yes, she was completely right. The point is that IDisposable has nothing to do with the garbage collector. Disposed does not mean garbage collected.

like image 80
Luaan Avatar answered Sep 28 '22 17:09

Luaan