Summary
FileInputStream and FileOutputStream and subclasses should have more flexibility to implement the closing of FileDescriptors and release other resources when the streams are unreferenced. Requiring use of finalization in all cases has a negative performance impact.
Problem
The use of finalization by FIS/FOS to close file descriptors adds a significant overhead to garbage collection and reference processing of finalizable references.
The specification of FileInputStream and FileOutputStream finalize methods requires the close
method to be called when "there are no more references to it". As written implies, but does not mandate that finalize
calls close
though that is the current implementation.
A clarification can enable a more efficient implementation.
Also, the deprecation of the finalize
methods should include forRemoval = true
to give adequate notice of future removal of the finalize
method.
Solution
The specifications of FileInputStream and FileOutputStream are changed to require the calling of close
when "there are no more references to it" only in the case where it would affect a subclass that has overridden either 'finalize' or 'close'.
It is also explicit that finalize
does not call close directly.
In other cases, the release of resources is implementation specific.
This conditional use of finalization allows the implementation flexibility to use finalization (but not necessarily the finalize
method) to call close
in cases where it may affect subclass behavior. Compatibility with current behavior is maintained except for the case where finalize
is called directly, which is not usually the case.
12/5/2017: Update to simplify the condition under which the close
method is called to depend only on the close
method being overridden.
The finalize
method is not longer included in the condition.
Specification
java.io.FileInputStream
Class javadoc:
+ * @apiNote
+ * To release resources used by this stream {@linkplain #close} should be called
+ * directly or by try-with-resources. Subclasses are responsible for the cleanup
+ * of resources acquired by the subclass.
+ * Subclasses that override {@link #finalize} in order to perform cleanup
+ * should be modified to use alternative cleanup mechanisms such as
+ * {@link java.lang.ref.Cleaner} and remove the overriding {@code finalize} method.
+ *
+ * @implSpec
+ * If this FileInputStream has been subclassed and the {@linkplain #close}
+ * method has been overridden, the {@linkplain #close} method will be
+ * called when the FileInputStream is unreachable.
+ * Otherwise, it is implementation specific how the resource cleanup described in
+ * {@linkplain #close} is performed.
Method finalize():
/**
* Ensures that the {@linkplain #close} method of this file input stream is
* called when there are no more references to it.
+ * The {@link #finalize} method does not call {@linkplain #close} directly.
*
+ * @implSpec
+ * If this FileInputStream has been subclassed and the {@linkplain #close}
+ * method has been overridden, the {@linkplain #close} method will be
+ * called when the FileInputStream is unreachable.
+ * Otherwise, it is implementation specific how the resource cleanup described in
+ * {@linkplain #close} is performed.
+ *
+ * @apiNote
+ * To release resources used by this stream {@linkplain #close} should be called
+ * directly or by try-with-resources.
+ *
+ * @deprecated The {@code finalize} method has been deprecated and will be removed.
* Subclasses that override {@code finalize} in order to perform cleanup
* should be modified to use alternative cleanup mechanisms and
* to remove the overriding {@code finalize} method.
@@ -425,15 +460,39 @@
* @exception IOException if an I/O error occurs.
* @see java.io.FileInputStream#close()
*/
+ @Deprecated(since="9", forRemoval = true) {...}
java.io.FileOutputStream
Class javadoc:
+ * @apiNote
+ * To release resources used by this stream {@linkplain #close} should be called
+ * directly or by try-with-resources. Subclasses are responsible for the cleanup
+ * of resources acquired by the subclass.
+ * Subclasses that override {@link #finalize} in order to perform cleanup
+ * should be modified to use alternative cleanup mechanisms such as
+ * {@link java.lang.ref.Cleaner} and remove the overriding {@code finalize} method.
+ *
+ * @implSpec
+ * If this FileOutputStream has been subclassed and the {@linkplain #close}
+ * method has been overridden, the {@linkplain #close} method will be
+ * called when the FileOutputStream is unreachable.
+ * Otherwise, it is implementation specific how the resource cleanup described in
+ * {@linkplain #close} is performed.
Method finalize():
/**
* Cleans up the connection to the file, and ensures that the
* {@linkplain #close} method of this file output stream is
* called when there are no more references to this stream.
+ * The {@link #finalize} method does not call {@linkplain #close} directly.
+ *
+ * @implSpec
+ * If this FileOutputStream has been subclassed and the {@linkplain #close}
+ * method has been overridden, the {@linkplain #close} method will be
+ * called when the FileOutputStream is unreachable.
+ * Otherwise, it is implementation specific how the resource cleanup described in
+ * {@linkplain #close} is performed.
+ *
+ * @apiNote
+ * To release resources used by this stream {@linkplain #close} should be called
+ * directly or by try-with-resources.
+ *
+ * @deprecated The {@code finalize} method has been deprecated and will be removed.
+ * Subclasses that override {@code finalize} in order to perform cleanup
+ * should be modified to use alternative cleanup mechanisms and
+ * to remove the overriding {@code finalize} method.
+ * When overriding the {@code finalize} method, its implementation must explicitly
+ * ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}.
+ * See the specification for {@link Object#finalize()} for further
+ * information about migration options.
*
* @exception IOException if an I/O error occurs.
* @see java.io.FileInputStream#close()
*/
+ @Deprecated(since="9", forRemoval = true)
protected void finalize() throws IOException {...}
- csr of
-
JDK-8080225 FileInput/OutputStream/FileChannel cleanup should be improved
- Resolved
- relates to
-
JDK-8192939 Remove Finalize methods from FileInputStream and FileOutputStream
- Resolved
-
JDK-8193190 (jdeprscan) Add checks for overridden finalize methods and related dependencies such as close()
- Open
-
JDK-8187485 Update Zip implementation to use Cleaner, not finalizers
- Closed
-
JDK-8212050 Remove Finalize methods from FileInputStream and FileOutputStream
- Closed