Tuesday, February 15, 2005

Destructors in GCed languages

Based on a conversation with Walter Bright, the creator of the D Language, a summary of my thinking on destructors in GCed languages:

1) If you have scoped objects, they can automatically call destructors at the end of the scope, because it's deterministic. However, this could cause confusion with:

2) Heap based objects should not have destructors called automatically, because garbage collection is not deterministic. If cleanup other than memory release is necessary, the programmer should be forced to decide when this happens, presumably with finally clauses. If cleanup is necessary, it must be determined by the programmer because the GC is nondeterministic. This leads to:

3) The value of the destructor for GCed objects is that it automatically calls base-class destructors in the proper order (most-derived first). Java abdicates any responsibility for cleanup other than memory release, which forces the programmer to generate their own "cleanup" methods and to be dilligent about proper order.

4) The biggest remaining problem is member-object cleanup. Member objects need to be cleaned up in reverse order of initialization. A destructor should automatically call member-object destructors, and if you don't expect the GC to call the destructor (which doesn't work anyway), you can assume that all member objects are still alive when the destructor is called. Therefore it is safe for the member object destructors to be called. Without this the solution is incomplete.

5) The one thing I could see adding to D is functionality to verify that destructors have been called if they exist. This would close the loop and solve the problem of destructors with GCed objects. The key is that the GC can't do it (as the Java designers learned with the multi-year finalize() debacle). But the GC can verify that destructible objects have had their destructors called by the time the GC is releasing the object.

Note that Python is able to get away with automatic destructor calls because it uses reference counting and thus the moment the reference count goes to zero the destructor is called. I.e.: it's deterministic in Python.

MindView Home Page