MaxMetaspaceSize and CompressedClassSpaceSize

Stefan Karlsson stefan.karlsson at oracle.com
Wed Jun 17 06:14:14 UTC 2015


On 2015-06-17 02:02, Yasumasa Suenaga wrote:
> Hi Stefan,
>
>> I don't understand what you want to say with the last to paragraphs.
>
> I want to say about sun.misc.Launcher$AppClassLoader .
> I think this class loader will be created certainly at boot time,
> and it will have NonClassType Metaspace.

OK.

>
>
>>>> Maybe it would be enough for you to implement the suggested 
>>>> MIN(CompressedClassSpaceSize, MaxMetaspaceSize) patch?
>
> Should I resize CompressedClassSpaceSize than to show error message?

If you add slightly better heuristics for the setup of the 
CompressedClassSpaceSize flag, for example lowering the 
CompressedClassSpaceSize when MaxMetaspaceSize is set, then it might be 
less likely that you'll hit the OutOfMemoryError when the system is set 
up with strict overcommit settings.

StefanK

>
>
> Thanks,
>
> Yasumasa
>
>
> On 2015/06/17 4:30, Stefan Karlsson wrote:
>> On 2015-06-12 15:41, Yasumasa Suenaga wrote:
>>> Hi Stefan,
>>>
>>>> Maybe it would be enough for you to implement the suggested 
>>>> MIN(CompressedClassSpaceSize, MaxMetaspaceSize) patch?
>>>
>>> I think that we have to calculate CompressedClassSpaceSize as well as
>>> InitialBootClassLoaderMetaspaceSize.
>>> If it is correct, I want to scale CompressedClassSpaceSize:
>>>
>>>   <new CompressedClassSpaceSize> = MaxMetaspaceSize - 
>>> InitialBootClassLoaderMetaspaceSize
>>
>> I think it makes sense to subtract the 
>> InitialBootClassLoaderMetaspaceSize from the calculation, since it's 
>> used as the size of the first non-class metaspace chunk allocation.
>>
>>>
>>> Of course, it is not enough.
>>> VirtualSpaceList will be created per class loader, and Java will 
>>> have one application
>>> class loader at least.
>>>
>>> However, it is difficult to calculate all metaspace at boot time.
>>> So I use CompressedClassSpaceSize and 
>>> InitialBootClassLoaderMetaspaceSize as parameters.
>>>
>>>
>>> What do you think?
>>
>> I don't understand what you want to say with the last to paragraphs.
>>
>> StefanK
>>
>>>
>>> Yasumasa
>>>
>>>
>>>
>>> On 2015/06/12 17:41, Stefan Karlsson wrote:
>>>> On 2015-06-12 02:57, Jon Masamitsu wrote:
>>>>>
>>>>>
>>>>> On 6/11/2015 5:09 PM, Yasumasa Suenaga wrote:
>>>>>> Hi Jon,
>>>>>>
>>>>>>> Please send the hs_err log.  It will have a better description 
>>>>>>> of the heap.
>>>>>> This is not crash (OutOfMemoryError). So I do not have hs_err log.
>>>>>>
>>>>>>
>>>>>>> The CompressedClassSpaceSize is the size reserved for the Class 
>>>>>>> space.  The
>>>>>>> size of the compressed-class-space is included in the comparison 
>>>>>>> with
>>>>>>> MaxMetaspaceSize
>>>>>>> only when the space is committed.  So no, it should not be 
>>>>>>> compared to the
>>>>>>> MaxMetaspaceSize at initialization.
>>>>>> Reserved memory will affect overcommit memory in OS.
>>>>>> In case of Linux, it may cause of OOM-killer.
>>>>>> So I want to check CompressedClassSpaceSize before initialization.
>>>>>>
>>>>>>> I would fix this in share/vm/memory/metaspace.cpp
>>>>>>>
>>>>>>> Metaspace::global_initialize()
>>>>>>>
>>>>>>> in the calculation of _first_chunk_word_size.
>>>>>>>
>>>>>>>        _first_chunk_word_size = 
>>>>>>> MIN2(InitialBootClassLoaderMetaspaceSize,
>>>>>>> MaxMetaspaceSize) / BytesPerWord;
>>>>>> Thank you for your suggestion.
>>>>>> May I file it to JBS?
>>>>>
>>>>> I don't think that limiting  CompressedClassSpaceSize by 
>>>>> MaxMetaspaceSize is a good
>>>>> thing to do.  Certainly not on systems which don't have 
>>>>> OOM-killer. There is an easy work around
>>>>> and sometimes it is better to use the workaround than to make the 
>>>>> JVM do something
>>>>> automatically that may seem right in some situations but may not 
>>>>> be right in others.
>>>>
>>>> The proposed patch breaks the usage of the -XX:MaxMetaspaceSize flag.
>>>>
>>>> $ ../build/linux-x86_64-normal-server-release/jdk/bin/java 
>>>> -XX:MaxMetaspaceSize=128m
>>>> Error occurred during initialization of VM
>>>> Sum of InitialBootClassLoaderMetaspaceSize and 
>>>> CompressedClassSpaceSize should be less than MaxMetaspaceSize.
>>>>
>>>>
>>>> We talked about something similar in this thread:
>>>> http://mail.openjdk.java.net/pipermail/hotspot-runtime-dev/2015-April/014425.html 
>>>>
>>>>
>>>> where I wrote:
>>>> "However, as you've noted we pre-reserve 1GB, and not 32 MB, for 
>>>> the compressed class space. That can be fixed by either running 
>>>> with -XX:CompressedClassSpaceSize=32m, or by a patch to change the 
>>>> implementation to only reserve MIN(CompressedClassSpaceSize, 
>>>> MaxMetaspaceSize) for the compressed class space.
>>>>
>>>> Maybe it would be enough for you to implement the suggested 
>>>> MIN(CompressedClassSpaceSize, MaxMetaspaceSize) patch?
>>>>
>>>> StefanK
>>>>
>>>>>
>>>>> You are, of course,  free to file a JBS and have it considered by 
>>>>> more than just me.
>>>>>
>>>>> Jon
>>>>>
>>>>>>
>>>>>>
>>>>>> Thanks,
>>>>>>
>>>>>> Yasumasa
>>>>>>
>>>>>>
>>>>>> On 2015/06/12 4:01, Jon Masamitsu wrote:
>>>>>>> On 06/11/2015 03:52 AM, Yasumasa Suenaga wrote:
>>>>>>>> Hi all,
>>>>>>>>
>>>>>>>> I booted Tomcat 8 with "-XX:MaxMetaspaceSize=5m 
>>>>>>>> -XX:+PrintGCDetails",
>>>>>>>> but it failed.
>>>>>>>> I checked GC log, Java heap and Metaspace was NOT exhausted.
>>>>>>> Please send the hs_err log.  It will have a better description 
>>>>>>> of the heap.
>>>>>>>
>>>>>>>> ------------
>>>>>>>> [Full GC (Last ditch collection) [Tenured: 
>>>>>>>> 1049K->1049K(10944K), 0.0050992 secs] 1049K->1049K(15936K), 
>>>>>>>> [Metaspace: 4871K->4871K(1056768K)], 0.0051411 secs] [Times: 
>>>>>>>> user=0.01 sys=0.00, real=0.00 secs]
>>>>>>>> [Full GC (Metadata GC Threshold) [Tenured: 
>>>>>>>> 1049K->1049K(10944K), 0.0050587 secs] 1049K->1049K(15936K), 
>>>>>>>> [Metaspace: 4871K->4871K(1056768K)], 0.0051023 secs] [Times: 
>>>>>>>> user=0.00 sys=0.00, real=0.01 secs]
>>>>>>>> [Full GC (Last ditch collection) [Tenured: 
>>>>>>>> 1049K->1049K(10944K), 0.0050200 secs] 1049K->1049K(15936K), 
>>>>>>>> [Metaspace: 4871K->4871K(1056768K)], 0.0050613 secs] [Times: 
>>>>>>>> user=0.01 sys=0.00, real=0.00 secs]
>>>>>>>>
>>>>>>>> Exception: java.lang.OutOfMemoryError thrown from the 
>>>>>>>> UncaughtExceptionHandler in thread "main"
>>>>>>>> ------------
>>>>>>>>
>>>>>>>> My environment:
>>>>>>>>      Fedora22 x86_64
>>>>>>>>       - kernel-4.0.4-303.fc22.x86_64
>>>>>>>>       - glibc-2.21-5.fc22.x86_64
>>>>>>>>       - java-1.8.0-openjdk-1.8.0.45-39.b14.fc22.x86_64
>>>>>>>>       - apache-tomcat-8.0.23
>>>>>>>>
>>>>>>>> This java process is enabled CompressedClassSpace (as default).
>>>>>>>> Metaspace size in GC log seems to be contained it (1GB).
>>>>>>>>
>>>>>>>> I checked arguments.cpp and metaspace.cpp, 
>>>>>>>> CompressedClassSpaceSize
>>>>>>>> does not seem to be checked consistent with MaxMetaspaceSize.
>>>>>>>>
>>>>>>>> Does JVM have to check CompressedClassSpaceSize and 
>>>>>>>> InitialBootClassLoaderMetaspaceSize
>>>>>>>> which are consistent with MaxMetaspaceSize?
>>>>>>> The CompressedClassSpaceSize is the size reserved for the Class 
>>>>>>> space.  The
>>>>>>> size of the compressed-class-space is included in the comparison 
>>>>>>> with
>>>>>>> MaxMetaspaceSize
>>>>>>> only when the space is committed.  So no, it should not be 
>>>>>>> compared to the
>>>>>>> MaxMetaspaceSize at initialization.
>>>>>>>
>>>>>>>> I think we can fix as below:
>>>>>>>> ------------
>>>>>>>> diff -r 85e2c3553384 src/share/vm/runtime/arguments.cpp
>>>>>>>> --- a/src/share/vm/runtime/arguments.cpp        Wed Jun 03 
>>>>>>>> 08:49:34 2015 +0900
>>>>>>>> +++ b/src/share/vm/runtime/arguments.cpp        Thu Jun 11 
>>>>>>>> 19:50:11 2015 +0900
>>>>>>>> @@ -2333,6 +2333,15 @@
>>>>>>>>       status = status && 
>>>>>>>> verify_interval(CompressedClassSpaceSize, 1*M, 3*G,
>>>>>>>> "CompressedClassSpaceSize");
>>>>>>>>
>>>>>>>> +  if (UseCompressedClassPointers) {
>>>>>>>> +    status = status &&
>>>>>>>> +         ((CompressedClassSpaceSize + 
>>>>>>>> InitialBootClassLoaderMetaspaceSize)
>>>>>>>> + <= MaxMetaspaceSize);
>>>>>>>> +  } else {
>>>>>>>> +    status = status &&
>>>>>>>> + (InitialBootClassLoaderMetaspaceSize <= MaxMetaspaceSize);
>>>>>>> I would fix this in share/vm/memory/metaspace.cpp
>>>>>>>
>>>>>>> Metaspace::global_initialize()
>>>>>>>
>>>>>>> in the calculation of _first_chunk_word_size.
>>>>>>>
>>>>>>>        _first_chunk_word_size = 
>>>>>>> MIN2(InitialBootClassLoaderMetaspaceSize,
>>>>>>> MaxMetaspaceSize) / BytesPerWord;
>>>>>>>
>>>>>>>
>>>>>>> Jon
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>> +  }
>>>>>>>> +
>>>>>>>>       status = status && verify_interval(MarkStackSizeMax,
>>>>>>>>                                       1, (max_jint - 1), 
>>>>>>>> "MarkStackSizeMax");
>>>>>>>>       status = status && verify_interval(NUMAChunkResizeWeight, 
>>>>>>>> 0, 100, "NUMAChunkResizeWeight");
>>>>>>>> ------------
>>>>>>>>
>>>>>>>>
>>>>>>>> If it is accepted as a bug, I will file it to JBS and upload 
>>>>>>>> webrev.
>>>>>>>>
>>>>>>>>
>>>>>>>> Thanks,
>>>>>>>>
>>>>>>>> Yasumasa
>>>>>>>>
>>>>>
>>>>
>>



More information about the hotspot-gc-dev mailing list