Is a disposed object eligible for garbage collection? RRS feed

  • Question

  • Once an object is 'unreachable' it becomes eligible for gc. Is a disposed object considered 'unreachable'?

    E.g., if I have a class member on a long lived object instance and I call dispose on that member, is it eligible for gc or does it have to actually go out of scope (i.e., be explicitely set to null or have the object instance become 'unreachable', etc). 
    Thursday, January 22, 2009 9:42 PM


  • No, a Disposed object is not automatically considered for GC. But before we get to that, let me clarify what Dispose is for...

    In a managed space, the .NET runtime handles all memory allocations and deallocations (with the GC), but you can never exactly tell when the runtime/GC will come in and free the memory. If all your objects are managed, that's not usually a problem. However, if your code is using handles or pointers to unmanaged memory or critical system resources, like say a File handle, then you must free it in a deterministic manner (meaning that you just can't wait until some magic runtime operation comes along to close a file handle). That code needs a Dispose method so you can explicitly close out the unmanaged resource explicitly when you need it to be closed. However, any managed object wrapped around that system resource is not elegible for GC until it loses all roots (becomes unreachable), which often means going out of scope. Setting references to null "might" cause an object to become unreachable, but you can't always guarantee that. If some other reference to the same object still exists, then it is still reachable. In that sense, you can't set an object reference to null and expect that this particular piece of code will immediately mark the object as unreachable. The object must have no other means (references) of contacting it available before it is considered unreachable.

    So let's take your case as an example. You have a long-lived object with a member that gets Disposed. All that normally does is free the unmanaged OS resources associated to that member object. The member object itself is still reachable because the long-lived parent object still has a reference to it. You could set that member to null, but what if some other piece of code is holding a reference to that object? For example, somewhere else in the application, another object has an internal member that was set like:
    myFieldReference = LongLivedObjectRef.DisposableMember.

    Now, when you call LongLivedObjectRef.DisposableMember = null, the DisposableMember object is still reachable by myFieldReference. Therefore, GC won't wipe it.
    -Rob Teixeira
    • Marked as answer by vtcoder Wednesday, January 28, 2009 8:25 PM
    Thursday, January 22, 2009 10:58 PM