Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8187325

Relax FileInputStream/FileOutputStream requirement to use finalize

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P3 P3
    • 10
    • core-libs
    • None
    • behavioral
    • low
    • Hide
      The change to clarify that calling `finalize` can not be expected to call `close` should have a negligible effect. The recommended use to free resources is to call close. If not closed explicitly, the resources will be released when the FIS/FOS becomes unreachable.
      Show
      The change to clarify that calling `finalize` can not be expected to call `close` should have a negligible effect. The recommended use to free resources is to call close. If not closed explicitly, the resources will be released when the FIS/FOS becomes unreachable.
    • Java API
    • SE

      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 {...}

            rriggs Roger Riggs
            rriggs Roger Riggs
            Alan Bateman, Brian Burkhalter, Chris Hegarty
            Votes:
            0 Vote for this issue
            Watchers:
            9 Start watching this issue

              Created:
              Updated:
              Resolved: