This was a doubt someone asked me recently. The doubt was specific to Java but i consider it to apply to all reference counted systems (.NET / JavaScript etc)

Consider a class box.

Box b1 = new Box();
Box b2 = b1;
b1 = null;

B1 is set to null but b2 still points to the original object. How is this? Why is b2 not destroyed


B1 = new Box
  • Box is created in memory (say at address 123)
  • Box object reference count is set to 1
  • B1 = 123
B2 = B1
  • Box object reference count is incremented by 1 ie Reference count = 2
  • B2 = 123
B1 = Null
  • Box object reference count is decremented by 1
  • If Box object reference count = 0 if yes destroy box object
At this point there are outstanding references to the Box object ie In plain words, the reference count of the object is not zero. This is the reason why the object does not get destroyed when B1 alone is set to null.
B2 = Null
  • Box object reference is decremented by 1
  • Reference count now becomes 0 and box object is destroyed

Object Deletion

At the point in time the reference count of the object goes to zero, the object will be considered safe for deletion.

But the actual cleanup of the object might not happen at that point. This i because the garbage collector has to run to determine and traverse all the objects that are ready for destruction and reclaim their memory. This is a rather pain in the neck and often causes large memory pile ups for some kind-of programs and you might then have to manually cause the GC to run.

When the GC runs, it will call the destructor (finalize() in Java-ese) of the object. So if you have some time bound programs that have to immediately perform some stuff when all the references go to zero, you cant depend on finalize().

Hope that makes everything clear.

Corollary : The sysytem of outstanding references work in a recursive manner. (SO every time you add a reference to a particualr object, references to all objects within it must also incremented. This creates chains of references, which are sometimes hard to debug.

In fact i have heard folks who have moved to Java and .NET from C++ complain about this. In C++ you can delete an object by calling delete on the pointer. The object would get destroyed then and there.

But this never happens in GC environments. You have to make sure all the references are gone away. It is up to you to decide which is harder.

Personally, I think that it might be possible to mathematically prove that the GC reference counting scenario has more complexity.