Why is finalize () only called once by garbage collector?


Quotes from SCJP 6 study guide:

In the finalize() method you could write code that passes a reference to the object in question back to another object, effectively uneligiblizing the object for garbage collection. If at some point later on this same object becomes eligible for garbage collection again, the garbage collector can still process this object and delete it. The garbage collector, however, will remember that, for this object, finalize() already ran, and it will not run finalize() again

Why is it designed so? The purpose of the finalize() method still holds good even when the object is marked of collection second time. Then why Java decides to skip call to finalize()?

I don't know if its the original reason, but the current implementation enqueues Finalizer instances (internal subclass of Reference) for objects overriding the finalize method with an internal ReferenceQueue that gets polled by a dedicated FinalizerThread.

And because the JVM has no way of knowing whether the object would need to be finalized a second time it cannot decide whether it would have to enqueue a new Finalizer once the finalize() method has been called.

Anyway, you should avoid using finalize(). It makes object allocation more costly, prevents escape analysis and is not a very reliable way of managing native resources because the GC can postpone the finalization for an unbounded amount of time.