RFR JDK-8185582, Update Zip implementation to use Cleaner, not finalizers
Peter Levart
peter.levart at gmail.com
Fri Sep 29 20:18:59 UTC 2017
Hi Sherman,
I looked into ZipFile as promised.
One thing I noticed is that FinalizeZipFile.java test fails compilation:
test/jdk/java/util/zip/ZipFile/FinalizeZipFile.java:49: error: unreported exception Throwable; must be caught or declared to be thrown
super.finalize();
^
(the overridden finalize() in InstrumentedZipFile should now declare
throws Throwable, since it overrides Object.finalize() and not
ZipFile.finalize() which is gone).
The other thing I noticed is that Releaser 1st closes the streams (that
are still reachable via streams WeakHashMap) and also ends the
associated inflaters. But closing the stream will already release the
inflater (in case it is a ZipFileInflaterInputStream) into the inflaters
cache and the cache is scanned and inflaters ended later.
So we don't need a stream -> inflater association outside the stream in
the form of WeekHashMap. But we still need to keep the set of input
streams weakly reachable from ZipFile in case we want to close the
ZipFile explicitly (and there is no harm although useless if this also
happens as a result of automatic ZipFile cleaner processing).
This could be implemented in a form of:
final Set<InputStream> streams = Collections.newSetFromMap(new
WeakHashMap<>());
I also noticed that it is useless to test whether the inflater is
ended() when obtaining it from or releasing it into cache if the code
keeps the invariant that it never ends inflaters while they are still in
cache or associated with the open stream (the only place where inflaters
should be ended explicitly is in the Releaser). To make this even more
obvious, it might be good to move the obtaining/releasing logic directly
into the ZipFileInflaterInputStream constructor which would be passed a
reference to the inflatersCache instead of the Inflater instance.
Here's what I have in mind (I cahnged just the ZipFile and FinalizeZipFile):
http://cr.openjdk.java.net/~plevart/jdk10-dev/8185582_ZIP.cleaner/webrev.01/
What do you think?
Because Inflaters used in ZipFile will never be automatically ended by
their own cleaners (they are kept strongly reachable in the cache of
inflaters, which is strongly reachable from the registered ZipFile
cleanup function), it might be useful to add a special package-private
constructor to Inflater which would not register its own cleaner. But
this could be left as an exercise for some later time.
Regards, Peter
On 09/28/17 01:41, Xueming Shen wrote:
> Thanks Mandy!
>
> I removed the ln#657-#663, and updated the @apiNote in deflter, inflater
> and zipfile accordingly, mainly combined your comment and the approach
> for the fis/fo. they are "simpler" and straightforward now, at least
> for me.
>
> https://bugs.openjdk.java.net/browse/JDK-8187485
> http://cr.openjdk.java.net/~sherman/8185582/webrev
>
> -Sherman
>
> On 9/27/17, 3:08 PM, mandy chung wrote:
>>
>> Comment on the CSR:
>>
>> On 9/26/17 11:35 PM, Xueming Shen wrote:
>>>
>>> csr: https://bugs.openjdk.java.net/browse/JDK-8187485
>>>
>> I think the @apiNote can be simpler.
>>
>> Deflater (similar comment for Inflater)
>> | * @apiNote
>> * In earlier versions, the {@link Object#finalize} method was
>> overridden
>> * to call the {@link #end} method when a {@code Deflater} object
>> * becomes unreachable.
>> * The {@link #finalize} method is no longer defined. If a subclass
>> * overrides||the {@code end} method, the overridden {@code end} method
>> * is no longer invoked.
>> *<p>
>> * It is strongly recommended to explicitly call {@code end} to
>> || * discard any unprocessed input promptly to free up resources
>> | * when|||the compressor|is no longer in use.|
>>
>>
>> |ZipFile
>> * @apiNote
>> | * In earlier versions, the {@link Object#finalize} method was
>> overridden
>> * to call the {@link #close} method when a {@code ZipFile} object
>> * becomes unreachable.|
>> | * The {@link #finalize} method is no longer defined. If a subclass
>> * overrides||the {@code close} method, the overridden {@code close}
>> method
>> * is no longer invoked.|
>> *<p>
>> | * The recommended cleanup for|||{@code ZipFile}| is to explicitly
>> call {@code close}
>> * or use try-with-resources.|
>>
>> 657 *<p>
>> 658 * Since the time when the resources held by this object
>> will be released
>> 659 * is undetermined, if this method is not invoked
>> explicitly, it is strongly
>> 660 * recommended that applications invoke this method as soon
>> they have
>> 661 * finished accessing this {@code ZipFile}. This will
>> prevent holding up
>> 662 * system resources for an undetermined length of time.
>> 663 *<p>
>>
>> I would suggest to drop this paragraph. @apiNote and @implNote in
>> class spec cover that.
>>
>> Mandy
>> ||
>
More information about the core-libs-dev
mailing list