...
Wiki Markup According to the Java Language Specification \[[JLS 2005|AA. Java References#JLS 05]\] Section 12.6.2 "Finalizer Invocations are Not Ordered":
This can be a problem as slow running finalizers tend to block others in the queue.Wiki Markup The Java programming language imposes no ordering on {{finalize}} method calls. Finalizers \[of different objects\] may be called in any order, or even concurrently.
...
- It is also imprudent to use finalizers for reclaiming scarce resources by enforcing garbage collection. Garbage collection usually depends on memory related traits and not on the scarcity of a particular resource. As a result, if memory is readily available, a scarce resource may get exhausted even in the presence of a finalizer. 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 resources correctly.
...
Wiki Markup It is not advisable to use any lock or sharing based mechanisms within a finalizer because of the inherent dangers of deadlock and starvation. On the other hand, it is easy to miss that there can be synchronization issues with the use of finalizers even if the source program is single-threaded. This is because the {{finalize()}} methods are called from their own threads (not from the {{main()}} thread). If a finalizer is necessary, the cleanup data structure should be protected from concurrent access. (See \[[Boehm 2005|AA. Java References#Boehm 05]\].).
Noncompliant Code Example
This noncompliant code example uses the System.runFinalizersOnExit()
method to simulate a garbage collection run (note that this method is deprecated because of thread-safety issues. (See guideline MET15-J. Do not use deprecated or obsolete methods.) .
Wiki Markup |
---|
According to the Java API \[[API 2006|AA. Java References#API 06]\] class {{System}}, {{runFinalizersOnExit()}} method documentation: |
Enable or disable finalization on exit; doing so specifies that the finalizers of all objects that have finalizers that have not yet been automatically invoked are to be run before the Java runtime exits. By default, finalization on exit is disabled.
The class SubClass
overrides the protected
finalize
method and performs cleanup activities. Subsequently, it calls super.finalize()
to make sure its superclass is also finalized. The unsuspecting BaseClass
calls the doLogic()
method which happens to be overridden in the SubClass
. This resurrects a reference to SubClass
such that it is not only prevented from being garbage collected but also from using its finalizer to close new resources that may have been allocated by the called method. As detailed in guideline MET04-J. Ensure that constructors do not call overridable methods, if the subclass's finalizer has terminated key resources, invoking its methods from the superclass might lead one to observe the object in an inconsistent state. In some cases this can result in the infamous NullPointerException
.
...
Improper use of finalizers can result in resurrection of garbage-collection ready objects and result in denial of service vulnerabilities.
Rule Guideline | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
OBJ08-J | medium | probable | medium | P8 | L2 |
...