Before the garbage collector acts on an object to reclaim it, the object's finalizer is executed. This is required to ensure that resources such as open streams, files and network connections get freed since resource management does not happen automatically while reclaiming memory. In Java, the finalize
method of java.lang.Object
is used to perform this activity.
The caveats associated with the usage of finalizers are discussed below:
finalize
method, for instance, closing file handles is not recommended.System.gc
, System.runFinalization
, System.runFinalizersOnExit
and Runtime.runFinalizersOnExit
are either just marginally better or have been deprecated due to lack of safety and deadlock causing effects.According to the Java Language Specification: \[[JLS 05|AA. Java References#JLS 05]\] Section 12.6.2: |
The Java programming language imposes no ordering on finalize method calls. Finalizers may be called in any order, or even concurrently.
finalize
method. While the garbage collector must determine yet again whether the object is free to be deallocated, the finalize
method is not invoked again.OBJ02-EX1: Sometimes it is necessary to use finalizers especially while working with native objects/code. This is because the garbage collector cannot re-claim memory from code written in another language. Again, the native process must not perform any critical jobs that require immediate resource deallocation.
In such cases, finalize
should be used correctly. Any subclass that overrides finalize
must explicitly invoke the method for its superclass as well. There is no automatic chaining with finalize
. The correct way to handle this is shown below.
protected void finalize() throws Throwable { try { //... } finally { super.finalize(); } } |
Alternatively, a more expensive solution is to declare an anonymous class so that the {{finalize}} method is guaranteed to run for the superclass. This solution is applicable to public non-final classes. "The finalizer guardian object forces {{super.finalize}} to be called if a subclass overrides finalize and does not explicitly call {{super.finalize}}". \[[JLS 05|AA. Java References#JLS 05]\] Section 12.6.1: Implementing Finalization. |
public class Foo { // The finalizeGuardian object finalizes the outer Foo object private final Object finalizerGuardian = new Object() { protected void finalize() throws Throwable { // Finalize outer Foo object } }; //... } |
Finalizers can have unexpected behavior.
Rule |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
OBJ02-J |
medium |
low |
high |
P??? |
L??? |
TODO
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
\[[JLS 05|AA. Java References#JLS 05]\] Section 12.6, Finalization of Class Instances \[[Bloch 08|AA. Java References#Bloch 08]\] Item 7, Avoid finalizers \[[Darwin 04|AA. Java References#Darwin 04]\] Section 9.5, The Finalize Method \[[Flanagan 05|AA. Java References#Flanagan 05]\] Section 3.3, Destroying and Finalizing Objects \[[API 06|AA. Java References#API 06]\] [finalize()|http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html#finalize()] |