jdk 8u40 - MaxMetaspaceSize and CompressedClassSpaceSize

Vitaly Davidovich vitalyd at gmail.com
Wed Apr 8 02:26:35 UTC 2015


Thanks Ramki, that does clear it up a bit.  So you're saying the JVM notion
of reserved is basically (on linux) mmap()'ing anon memory with PROT_NONE
equivalent - i.e. no commit charge.  Is that right?

Ok, so the issue with ulimit is probably that it actually restricts address
space, and not virtual memory.

As for the reservation in Hotspot, why is it reserving that address space
if it has no intention of using it? Or if it does use it, I'm assuming
it'll change protection on it and then possibly oom at that point (if
commit charge is over the limit).

But anyway, back to the question at hand.  Is there a single flag that
would cap the amount of VA requested? It seems odd that MaxMetaspaceSize by
itself doesn't change VA reservation, but adding CompressedClassSpaceSize
does.  Moreover, if I'm capping max size, why even reserve more VA in that
case?

Thanks

sent from my phone
On Apr 7, 2015 9:38 PM, "Srinivas Ramakrishna" <ysr1729 at gmail.com> wrote:

> Hi Vitaly --
>
> Let me give an example: In a multi-threaded process, if we want some piece
> of anon memory to be placed at a specific spot in our (i.e. process's) VA
> address space, we can first "reserve" that address space (tit is in that
> sense purely local to the process, there are no physical pages backing it,
> no swap reservation, no OS accounting, nothing). We then can decide at
> leisure what to do with that address space, knowing that that address space
> in our process is reserved for us and "no one can take that away from us."
> This is what the JVM calls an address space reservation.
>
> What the JVM calls "commit" is when we reserve the virtual memory with the
> OS. Committed memory may or may not be backed by physical pages. (For
> example, on Linux wjere you allow overcommit.) It's only when you access
> that page will it be faulted in from the set of free pages in RAM (if there
> are any left and you aren't overcommitted).
>
> What is confusing you (and many others) is the use of the term "reserved".
> Here reserved is used in the sense of reserving the address space in the
> process. Nothing else. No OS book-keeping to reserve virtual *memory*,
> nothing.
>
> At least that was what it was a couple of years ago, but I haven't looked
> at the code in recent times (but given this discussion, I'll go and do so
> soon!).
> -- ramki
>
>
> On Tue, Apr 7, 2015 at 5:47 PM, Vitaly Davidovich <vitalyd at gmail.com>
> wrote:
>
>> Ramki,
>>
>> I'm not sure I fully understand your distinction between virtual address
>> space vs virtual memory.  If you disable swap and overcommit and you
>> mmap/brk from the kernel, it has to ensure that the reservation could be
>> backed up if it were committed; if you take away swap and don't allow linux
>> to overpromise (i.e. overcommit), the malloc will fail.  See here for what
>> I'm talking about: http://www.etalabs.net/overcommit.html
>>
>> The committed memory is memory that is now backed by physical ram (or
>> swap), it has either been touched or manually committed - it's not a
>> reservation (which has no physical backing, just kernel VM accounting
>> behind it).
>>
>> Did I misunderstand you?
>>
>> sent from my phone
>> Hi Vitaly --
>>
>> The allocated (but not necessarily touched/faulted) memory reported above
>> (by the jvm) is the one corresponding to "committed". The "reservation"
>> reported above is only of the virtual *address space* within the process,
>> not virtual *memory*  (i.e. no swap reservations or the like). I didn't
>> know that ulimits could prevent virtual address space (_not_ virtual
>> memory) reservation.
>>
>> I think your question is valid, in that looking at the VA reservation,
>> one feels that the JVM might eventually decide to commit beyond the max
>> space you asked for in your command-line spec. At the very least it is
>> confusing, and someone who knows why could explain the reason for the
>> larger than user-requested VA space (not VA memory yet in yr snippet)
>> reservation when it won't be used  -- if it won't be used, and here I am
>> giving the benefit of the doubt to the JVM in that it'll never try to
>> commit those pages despite having reserved that in its virtual address
>> space.
>>
>> -- ramki
>>
>> On Tue, Apr 7, 2015 at 5:01 PM, Vitaly Davidovich <vitalyd at gmail.com>
>> wrote:
>>
>>> By the way, forgot to mention that while doing some searching around
>>> this, saw this: https://issues.apache.org/jira/browse/HADOOP-11364.  So
>>> anyone with multi-tenant servers that impose mem limits may hit this.  But
>>> again, I'm trying to understand the flags involved and not saying this is a
>>> big problem.
>>>
>>> sent from my phone
>>> On Apr 7, 2015 7:55 PM, "Vitaly Davidovich" <vitalyd at gmail.com> wrote:
>>>
>>>> Hi Ramki,
>>>>
>>>> I agree in principle that a 1GB reservation on 64bit isn't an issue in
>>>> and of itself.  The problem comes up, however, if a program is run with
>>>> ulimit on VA and someone sized their java app appropriately in, say, java
>>>> 7.  With java 8, there can be regressions.
>>>>
>>>> Second, if you disable swap and overcommit on linux, larger virtual mem
>>>> allocations may fail.
>>>>
>>>> Having said all that, I'm curious whether there's a way to restrict
>>>> this with 1 flag in java 8 and whether the linked documentation is correct
>>>> or not.
>>>>
>>>> Thanks
>>>>
>>>> sent from my phone
>>>> On Apr 7, 2015 7:26 PM, "Srinivas Ramakrishna" <ysr1729 at gmail.com>
>>>> wrote:
>>>>
>>>>> Hi Vitaly --
>>>>>
>>>>> Because reserved but unused virtual address space is, for all
>>>>> practical purposes today, irrelevant for 64 bit processes,
>>>>> a question to ask is what you see when you do this for 32-bit
>>>>> processes (where of course the oop compression
>>>>> comments wouldn't of course apply, but the amount of VA space used
>>>>> would be much more relevant and parsimony
>>>>> -- or lack thereof -- in VA space reservation would visibly affect the
>>>>> bottom-line in a 32-bit VA space).
>>>>>
>>>>> -- ramki
>>>>>
>>>>> On Tue, Apr 7, 2015 at 12:27 PM, Vitaly Davidovich <vitalyd at gmail.com>
>>>>> wrote:
>>>>>
>>>>>> Hi guys,
>>>>>>
>>>>>> It seems that putting a cap on MaxMetaspaceSize has no impact on
>>>>>> amount of
>>>>>> memory reserved *unless* CompressedClassSpaceSize is also set.  For
>>>>>> example,
>>>>>>
>>>>>> java -Xmx64m -XX:MaxMetaspaceSize=16m Test
>>>>>>
>>>>>> yields the following:
>>>>>>
>>>>>>  Metaspace       used 2421K, capacity 4486K, committed 4864K, reserved
>>>>>> 1056768K
>>>>>>   class space    used 261K, capacity 386K, committed 512K, reserved
>>>>>> 1048576K
>>>>>>
>>>>>> Adding -XX:CompressedClassSpaceSize=16m yields:
>>>>>>
>>>>>> Metaspace       used 2421K, capacity 4486K, committed 4864K, reserved
>>>>>> 24576K
>>>>>>   class space    used 261K, capacity 386K, committed 512K, reserved
>>>>>> 16384K
>>>>>>
>>>>>> According to
>>>>>>
>>>>>> http://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/considerations.html
>>>>>> :
>>>>>>
>>>>>> >
>>>>>> > If UseCompressedOops is turned on and UseCompressedClassesPointers
>>>>>> is
>>>>>> > used, then two logically different areas of native memory are used
>>>>>> for
>>>>>> > class metadata. UseCompressedClassPointers uses a 32-bit offset to
>>>>>> > represent the class pointer in a 64-bit process as does
>>>>>> UseCompressedOops for
>>>>>> > Java object references. A region is allocated for these compressed
>>>>>> class
>>>>>> > pointers (the 32-bit offsets). The size of the region can be set
>>>>>> with
>>>>>> > CompressedClassSpaceSize and is 1 gigabyte (GB) by default. The
>>>>>> space for
>>>>>> > the compressed class pointers is reserved as space allocated by
>>>>>> mmap at
>>>>>> > initialization and committed as needed. The MaxMetaspaceSize
>>>>>> applies to
>>>>>> > the sum of the committed compressed class space and the space for
>>>>>> the other
>>>>>> > class metadata.
>>>>>>
>>>>>>
>>>>>> Unless I'm misunderstanding, the last sentence there seems to imply
>>>>>> that
>>>>>> MaxMetaspaceSize would put a cap on the compressed class space as
>>>>>> well.  Or
>>>>>> is the "committed" part of the last sentence the key? There's no way
>>>>>> to cap
>>>>>> the *reserved* amount with 1 flag? Basically, what's the java 8
>>>>>> equivalent
>>>>>> to MaxPermSize=X in java 7 and earlier?
>>>>>>
>>>>>> The reason this came up is because java 8 seems to have a much higher
>>>>>> virtual mem reserve charge than java 7, even for an app with a simple
>>>>>> main
>>>>>> that does nothing, and metaspace/compressed class space reservation
>>>>>> appears
>>>>>> to be the biggest contributor.
>>>>>>
>>>>>> Thanks
>>>>>>
>>>>>
>>>>>
>>
>


More information about the hotspot-runtime-dev mailing list