...
- There is no fixed time at which finalizers must be executed; this detail is depends on the JVM dependent. The only guarantee is that any finalizer method that executes will do so sometime after the associated object has become unreachable (detected during the first cycle of garbage collection), and sometime before the garbage collector reclaims the associated object's storage (during the garbage collector's second cycle). Execution of an object's finalizer can may be delayed for an arbitrarily long time after the object becomes unreachable. Consequently, avoid implementing time-critical functionality in an object's
finalize()
method. For instance, closing file handles in a finalizer is not recommended.
- The JVM can may terminate without invoking the finalizer on some or all unreachable objects. Consequently, attempts to update critical persistent state from finalizer methods can fail without warning. Similarly, Java provides no guarantee that finalizers will execute on process termination. Methods such as
System.gc()
,System.runFinalization()
,System.runFinalizersOnExit()
andRuntime.runFinalizersOnExit()
either lack such guarantees or have been deprecated because of lack of safety and potential for deadlock.
...
- Uncaught exceptions thrown during finalization are ignored. The finalization When an exception is thrown in a finalizer, the process itself immediately stops immediately, and consequently fails to accomplish its sole purpose.
- Coding errors that result in memory leaks prevent execution of finalizers for objects that imply that objects incorrectly remain reachable; thus their finalizers are never invoked.
- A programmer can unintentionally resurrect the an object's reference in the
finalize()
method. When this occurs, the garbage collector must determine yet again whether the object is free to be deallocated. Further, because thefinalize()
method has executed once, the garbage collector cannot invoke it a second time.
- Superclasses that use finalizers impose additional constraints on their extending classes. Consider an example from JDK 1.5 and earlier. The code snippet below allocates a 16 MB buffer used to back a Swing
Jframe
object. Although none of theJFrame
APIs have afinalize()
method,JFrame
extendsAWT.Frame
which does have afinalize()
method. When aMyFrame
object becomes unreachable, the garbage collector cannot reclaim the storage for the byte buffer because code in the inheritedfinalize()
method might refer to it. Consequently, the byte buffer must persist at least until the inheritedfinalize()
method for classMyFrame
completes its execution, and cannot be reclaimed until the following garbage collection cycle.
Code Block |
---|
Classclass MyFrame extends Jframe { private byte[] buffer = new byte[16 * 1024 * 1024]; // persists for at least two GC cycles } |
- Avoid using finalizers to reclaim release scarce resources as a side-effect of garbage collection. Garbage collection usually depends on memory availability and usage rather than on the scarcity of some other particular resource. Consequently, when memory is readily available, a scarce resource may be exhausted in spite of the presence of a finalizer that could reclaim release the scarce resource if it were executed. See guidelines FIO06-J. Ensure all resources are properly closed when they are no longer needed and TPS00-J. Use thread pools to enable graceful degradation of service during traffic bursts for more details on handling scarce resources correctly.
- A It is a common myth is that finalizers aid garbage collection. On the contrary, they increase garbage collection time and introduce space overheads. Finalizers interfere with the operation of modern generational garbage collectors by extending the lifetimes of many objects. Incorrectly programmed finalizers could also attempt to finalize reachable objects, which is always counterproductive and can violate program invariants.
...