--- old/src/java.base/share/classes/java/util/zip/Deflater.java 2017-12-04 13:50:34.217260334 -0800 +++ new/src/java.base/share/classes/java/util/zip/Deflater.java 2017-12-04 13:50:33.714214957 -0800 @@ -67,12 +67,19 @@ * } * * + * @apiNote + * To release resources used by this {@code Deflater}, the {@link #end()} method + * should be called explicitly. 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. + * * @see Inflater * @author David Connelly * @since 1.1 */ -public -class Deflater { + +public class Deflater { private final ZStreamRef zsRef; private byte[] buf = new byte[0]; @@ -169,7 +176,9 @@ public Deflater(int level, boolean nowrap) { this.level = level; this.strategy = DEFAULT_STRATEGY; - this.zsRef = new ZStreamRef(init(level, DEFAULT_STRATEGY, nowrap)); + this.zsRef = ZStreamRef.get(this, + () -> init(level, DEFAULT_STRATEGY, nowrap), + Deflater::end); } /** @@ -534,38 +543,37 @@ /** * Closes the compressor and discards any unprocessed input. + * * This method should be called when the compressor is no longer - * being used, but will also be called automatically by the - * finalize() method. Once this method is called, the behavior - * of the Deflater object is undefined. + * being used. Once this method is called, the behavior of the + * Deflater object is undefined. */ public void end() { synchronized (zsRef) { - long addr = zsRef.address(); - zsRef.clear(); - if (addr != 0) { - end(addr); - buf = null; - } + zsRef.clean(); + buf = null; } } /** * Closes the compressor when garbage is collected. * - * @deprecated The {@code finalize} method has been deprecated. - * 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. - */ - @Deprecated(since="9") - protected void finalize() { - end(); - } + * @implSpec + * If this {@code Deflater} has been subclassed and the {@code end} method + * has been overridden, the {@code end} method will be called when the + * inflater is unreachable. + * + * @deprecated The {@code finalize} method has been deprecated and + * implemented as a no-op. 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. The recommended cleanup for compressor is to explicitly + * call {@code end} method when it is no longer in use. If the + * {@code end} is not invoked explicitly the resource of the compressor + * will be released when the instance becomes phantom-reachable. + */ + @Deprecated(since="9", forRemoval=true) + protected void finalize() {} private void ensureOpen() { assert Thread.holdsLock(zsRef);