JDK-8276748 : Deprecate finalization-related methods for removal
  • Type: CSR
  • Component: core-libs
  • Priority: P4
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 18
  • Submitted: 2021-11-05
  • Updated: 2021-11-19
  • Resolved: 2021-11-17
Related Reports
CSR :  
Relates :  
Description
Summary
-------
Deprecate finalization-related methods for removal, per [JEP 421][1] ("Deprecate Finalization for Removal").

Problem
-------
Finalization has several critical, fundamental flaws. These were widely recognized early in Java's history, and the JDK has offered better alternatives for quite some time. JEP 421 deprecates finalization for removal. The deprecations should be reflected in the API specification.

Solution
--------
Several `finalize()` methods are already ordinarily deprecated. They will be upgraded to terminal deprecation by adding `forRemoval=true`:

 * `java.lang.Object.finalize()`
 * `java.lang.Enum.finalize()`
 * `java.awt.Graphics.finalize()`
 * `java.awt.PrintJob.finalize()`
 * `java.util.concurrent.ThreadPoolExecutor.finalize()`
 * `javax.imageio.spi.ServiceRegistry.finalize()`
 * `javax.imageio.stream.FileCacheImageInputStream.finalize()`
 * `javax.imageio.stream.FileImageInputStream.finalize()`
 * `javax.imageio.stream.FileImageOutputStream.finalize()`
 * `javax.imageio.stream.ImageInputStreamImpl.finalize()`
 * `javax.imageio.stream.MemoryCacheImageInputStream.finalize()`

Two methods will be newly deprecated with `forRemoval=true`:

 * `java.lang.Runtime.runFinalization()`
 * `java.lang.System.runFinalization()`.

One method will be newly deprecated with `forRemoval=false`:

 * `java.lang.management.MemoryMXBean.getObjectPendingFinalizationCount()`.

`MemoryMXBean` is an interface.  Removing a method from it could adversely impact existing implementations. While developers should avoid using this method, it's safe to leave it in place.  When finalization is disabled (or removed), this method will always return zero.


Specification
-------------
See attached webrev, also available at:

[http://cr.openjdk.java.net/~bchristi/8276748/webrev-CSR-03-8276748/][2]

  [1]: https://openjdk.java.net/jeps/421 "JEP 421"
  [2]: http://cr.openjdk.java.net/~bchristi/8276748/webrev-CSR-03-8276748/
Comments
Note that this specification change mentions the possibility that finalization can be disabled. This is supported by changes to the JLS and to the Java SE Platform Specification that are covered by CSR JDK-8276773.
19-11-2021

Moving amended request back to Approved; thanks.
17-11-2021

A couple suggested editorial changes have been applied to Object.finalize: - "JVM" -> "Java virtual machine" - "GC" -> "garbage collector" small - editorial change in the @deprecated text - 2nd paragraph is made boldface Also, a @jls 12.6 link has been added to [System|Runtime].runFinalization. The webrev has been updated. The added change is: --- a/src/java.base/share/classes/java/lang/Object.java +++ b/src/java.base/share/classes/java/lang/Object.java @@ -480,6 +480,7 @@ public class Object { * <p> - * When running in a JVM in which finalization has been disabled or removed, - * the garbage collector will never call {@code finalize()}. In a JVM in - * which finalization is enabled, the GC might call {@code finalize} only - * after an indefinite delay. + * <b>When running in a Java virtual machine in which finalization has been + * disabled or removed, the garbage collector will never call + * {@code finalize()}. In a Java virtual machine in which finalization is + * enabled, the garbage collector might call {@code finalize} only after an + * indefinite delay.</b> * <p> @@ -550,6 +551,7 @@ public class Object { * - * @deprecated Finalization has been deprecated for removal in a future - * release. Finalization can lead to problems with security, performance, - * and reliability. See <a href="https://openjdk.java.net/jeps/421">JEP 421</a> - * for discussion and alternatives. + * @deprecated Finalization is deprecated and subject to removal in a future + * release. The use of finalization can lead to problems with security, + * performance, and reliability. + * See <a href="https://openjdk.java.net/jeps/421">JEP 421</a> for + * discussion and alternatives. * <p> diff --git a/src/java.base/share/classes/java/lang/Runtime.java b/src/java.base/share/classes/java/lang/Runtime.java index 8571ed94292..0e3f3c0ff55 100644 --- a/src/java.base/share/classes/java/lang/Runtime.java +++ b/src/java.base/share/classes/java/lang/Runtime.java @@ -696,2 +696,3 @@ public class Runtime { * @see java.lang.Object#finalize() + * @jls 12.6 Finalization of Class Instances */ diff --git a/src/java.base/share/classes/java/lang/System.java b/src/java.base/share/classes/java/lang/System.java index b6845e081af..4e168a20a09 100644 --- a/src/java.base/share/classes/java/lang/System.java +++ b/src/java.base/share/classes/java/lang/System.java @@ -1927,2 +1927,3 @@ public final class System { * @see java.lang.Runtime#runFinalization() + * @jls 12.6 Finalization of Class Instances */
17-11-2021

Moving to Approved.
17-11-2021

Updated the proposed changes to Object.finalize with more actionable guidance, and a disclaimer.
16-11-2021

Moving back to Provisional. In terms of information contained strictly within the docs themselves, the earlier explicit guidance like 89 * Subclasses that override {@code finalize} in order to perform cleanup 90 * should be modified to use alternative cleanup mechanisms and 91 * to remove the overriding {@code finalize} method. seems more specific and directly actionable, i.e. "get rid of your own finalize() override" than the current text on Object.finalize. I recommend includes text like that in Object.finalize or preserving the existing instances of this guidance. Also, to not bury the lede, the start of the specs of Object.finalize should be updated as well. For example, after 476 * Called by the garbage collector on an object when garbage collection 477 * determines that there are no more references to the object. some disclaimer that this might not happen depending on how the VM was invoked, etc.
15-11-2021

Updated the proposed changes, and moved back to...Finalized.
12-11-2021

Moving to Provisional, not Approved. As a code review comment, Enum.finalize() is being deprecated in JDK 18, not JDK 9. If the runFinalization methods are being changed to have a higher likelihood of doing nothing, that should be surfaced more prominently int their specifications.
10-11-2021