RFR: 8156484: ZipFile retains too much native memory from caching Inflaters
Peter Levart
peter.levart at gmail.com
Thu May 19 16:49:20 UTC 2016
On 05/19/2016 06:31 PM, Xueming Shen wrote:
>
> Martin,
>
> Given we now only cache one deflater per Zip/JarFile object, is
> WeakReference here really
> necessary? Basically wr is based on the vm heap memory and deflater is
> a native memory,
> arguably we are using the wrong measurement to decide whether or not
> to give up the
> deflater's native memory. Given someone (classloader) is keeping
> hundreds and thousands
> of jar/zip files alive, is it reasonable to assume it'd better to keep
> the 32k cache for each
> of them?
It would perhaps make more sense to keep a 32k native object for each
thread - not each jar file, don't you think?
Regards, Peter
>
> -Sherman
>
> On 5/19/16 8:00 AM, Martin Buchholz wrote:
>> On Thu, May 19, 2016 at 7:29 AM, Peter Levart
>> <peter.levart at gmail.com> wrote:
>>> But I have reservation for the implementation of one-element global
>>> cache of
>>> Inflater. This cache can't be efficient. In order for cache to be
>>> efficient,
>>> majority of calls to ZipFile.getInputStream(zipEntry) would have to be
>>> accompanied by a corresponding explicit close() for the input stream
>>> before
>>> the WeakReference to the cached Inflater is cleared.
>> That's my assumption. In most cases, failure to close something that
>> can be closed is a bug.
>> If there's code in the JDK that fails to do that, it should be fixed
>> independently.
>>
>>> The "assert !inf.ended()" in
>>> releaseInflater() can therefore fail as final() methods on individual
>>> objects that are eligible for finalization may be invoked in arbitrary
>>> order.
>> Yeah, that's a bug. We can only assert after we verify that the
>> Inflater is still weakly reachable.
>> Updating my webrev with:
>>
>> * Releases the Inflater for possible later reuse.
>> */
>> private static void releaseInflater(Inflater inf) {
>> - assert !inf.ended();
>> CachedInflater cachedInflater = inflaterCache.get();
>> if (inf != cachedInflater.get()) {
>> inf.end();
>> } else {
>> // "return" the Inflater to the "pool".
>> + assert !inf.ended();
>> inf.reset();
>> assert cachedInflater.inUse.get();
>> cachedInflater.inUse.set(false);
>
>
More information about the core-libs-dev
mailing list