> Robin Garner wrote: >> GC is triggered in two cases: 1) the user code calls System.gc(). 2) >> the >> heap fills up (for some suitable definition of 'fills up'). There is >> never any need for the VM code to call the garbage collector. > > Off tanget, but IMHO this is not strictly true: it depends on whether > VM native code relies on finalize() to free up its (non-heap) memory. > Here's an exmaple of this: > > http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4797189
Ahem. I don't think this contradicts what I said. One of the standard use cases for finalizers is to free up externally allocated resources when they are no longer required. Unfortunately the Java standard provides no timeliness requirements for finalizers. Finalization is triggered by the GC. The most sensible implementation appears to be that the GC maintains a set of objects that require finalization. At the end of each collection, the GC examines this list, and if any of them is dead, it notifies the finalizer thread that the finalizer should be executed, and revives the object so that the finalizer can access its state. In a generational collector, maximum efficiency is achieved by executing as few major collections as possible. Any object with a finalizer that manages to be promoted to the mature space will probably live way past the point where it becomes unreachable, and hang onto any non-java-heap resources it has acquired for quite a while. One solution might be to maintain a 'finalized' space that is scanned during every minor collection. It is probably the kind of thing you would want run-time configurable, because it could reduce the efficiency of the collector. IMO the question of how to best do reference type processing and finalization is still open. This is one of the reasons. But it's still the GC that decides when an object dies! cheers