Daniel Dekany wrote:
Friday, December 12, 2003, 7:37:24 PM, Stephen McConnell wrote:

b) When the VM *normally* shutted down, the finalize() of some otherwise
unreferenced objects will not be called, so the component will be
disintegrated without receiving dispose event. Yes, there is
System.runFinalizersOnExit but... well... in the JavaDocs: "Deprecated.
This method is inherently unsafe."

FYI

Per Tony Printezis, Sun GC devloper for ~5 years:

The finalize() method *may* be invoked at some unspecified time after the object becomes unreachable.

How Finalization Works
----------------------
How does it [finalization] work with the garbafe collector? Each instance of a class that has finalizer on is specially registered when it is allocated by the collector so the collector knows that an instance has a finalizer. So this means that the allocation is slightly slower, because you have to go through the extra step when you allocate such instances. When the collector finds that that instance is unreachable, it queues to what is referred to as the finalizer queue. After that at some point later in time, a thread called the finalizer thread runs over the finalizer queue and calls the finalized methods of the instances that have been enqueued there. And again after the finalized method on an instance has been called and when that instance becomes unreachable *again*, it has the storage reclaimed. Of course you ask why the instance has to become unreachable again, because what it was unreachable in the first place. Well, the finalized method can do anything including make that instance reachable again from a static field or whatever. This is a dumb finalizer method. However, users are dumb sometimes and the garbage collector implementors cannot assume that the users are going to do the right thing.


        Each instance
        1. Is registerd when allocated
        2. Is enqueued when it becomes ureachable
        3. Has the finalize() method invoked?
        4. Becomes unreachable again (if resurrected in step 3)
        5. Has the storage reclaimed

new --> GC --> finalizer --> GC

Basically, the GC's first collection of the old generation (heap) does not collect much (when you have finalizers), and then you have to repeat the old generation collections while the finalizer thread is kind of struggling to call the finalizers (and only when all of them have been called), the storage of those objects can be reclaimed.

Impact of Finalization
----------------------
Speed
+ Slower allocation (registration of the finalizer)
+ Finalizer thread affects GC scheduling (because the finalizer thread is calling the finalizers)


Heap size larger
+ Memory is retained longer

Collection pauses longer
+ Discovery and queuing (GC has to deal with more objects and also have to discover instances with finalizers on them and queue them)


GC-Friendly Finalization (proper use)
-------------------------------------
+ Use finalizers to only cleanup external resources
+ Suggestions:
- Limit the number of finalized objects
- Re-organize classes so finalizable objects holds no extra data
- Beware when extending finalizable objects in standard libs
- GUI elements, NIO buffers
+ Alternatives:
- Use java.lang.ref.WeakReference w/o finalizers if you want to do some post-mortem processing on objects




---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to