RFR: 8034852: Shrinking of Metaspace high-water-mark causes incorrect OutOfMemoryErrors or back-to-back GCs

Jon Masamitsu jon.masamitsu at oracle.com
Thu May 1 17:34:54 UTC 2014


Erik,

Change looks good.

Please add a comment explaining why we're using committed now and why
capacity did not work.  Basically an abbreviated version of your explanation
below.

Thanks.

Jon

On 4/30/2014 4:18 AM, Erik Helin wrote:
> Hi all,
>
> this patch solves a rather tricky problem with the sizing of Metaspace.
>
> The issue happens when the GC threshold for Metaspace (called
> "capacity_until_GC" in the code) becomes less than the committed 
> memory for Metaspace. Any calls to Metaspace::allocate that requires 
> committing more memory will then fail in 
> MetaspaceGC::allowed_expansion, because capacity_until_GC() < 
> MetaspaceAux::committed_memory(). The effect will be a
> full GC and after the GC we try to expand and allocate. After the 
> expansion and before the allocation, one of two things can happen:
>  1. capacity_until_GC is larger than the committed memory after the
>     expansion. The allocation will now succeed, but the next allocation
>     requiring a new chunk will *again* trigger a full GC. This pattern
>     will repeat itself for each new allocation request requiring a new
>     chunk.
>  2. capacity_until_GC is still less than the committed memory even
>     after the expansion. We throw a Java OOME (incorrectly).
>
> How can the GC threshold for Metaspace be less than the committed 
> memory? The problem is that MetaspaceGC::compute_new_size uses the field
> _allocated_capacity for describing the amount of memory in Metaspace 
> that is "in use". _allocated_capacity does not consider the memory in 
> the chunk free lists to be "in use", since memory in the chunk free 
> lists are supposed to be available for new allocations. The problem is 
> that the chunk free lists can become fragmented, and then the memory 
> is not available for all kinds of allocations.
>
> This patch change MetaspaceGC::compute_new_size to use
> MetaspaceAux::committed_memory for describing how much memory that is 
> "in use". The effect will be that memory in the chunk free lists will no
> longer be considered "in use" (but will of course be used for future 
> allocations where possible). This will prevent capacity_until_GC from 
> shrinking below the committed memory "by definiton", since 
> capacity_until_GC can't be lower than the memory that is "in use".
>
> Based on the results from the perf testing (see below), this change 
> has no performance impact.
>
> Webrev:
> http://cr.openjdk.java.net/~ehelin/8034852/webrev.00/
>
> Testing:
> - JPRT
> - Ad-hoc testing:
>   - Kitchensink
>   - Dacapo
>   - Medrec
>   - runThese
>   - Parallel Class Loading testlist
>   - Metaspace testlist
>   - GC nightly testlist
> - Perf testing:
>   - SPECjbb2005
>   - SPECjbb2013
>   - Derby
> - Derby regression tests
>
> Thanks,
> Erik



More information about the hotspot-dev mailing list