Java 8 reserves minimum 1G for Metaspace despite (Max)MetaspaceSize
Asked Answered
I

2

33

Java 8 reserves 1G for Metaspace just after it starts. It means that minimum metaspace size is 1G. But I set up MetaspaceSize to 300m and MaxMetaspaceSize to 400m. Why Java reserves more then I allow?

Java Version

$ java -version
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

VM Flags

$ jcmd 21689 VM.flags
21689:
-XX:CICompilerCount=3 -XX:ConcGCThreads=1 -XX:G1HeapRegionSize=1048576 -XX:InitialHeapSize=62914560 -XX:+ManagementServer -XX:MarkStackSize=4194304 -XX:MaxHeapSize=1006632960 -XX:MaxMetaspaceSize=399998976 -XX:MaxNewSize=603979776 -XX:MetaspaceSize=299999232 -XX:MinHeapDeltaBytes=1048576 -XX:NativeMemoryTracking=summary -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseG1GC 

NMT

[jetty9-proxy@bm01 bin]$ jcmd 21689 VM.native_memory
21689:

Native Memory Tracking:

Total: reserved=2769543KB, committed=1311159KB

-                     Class (reserved=1221904KB, committed=197904KB)
                            (classes #36543)
                            (malloc=3344KB #44041) 
                            (mmap: reserved=1218560KB, committed=194560KB) 

And just after start it was

Total: reserved=2402748KB, committed=150796KB     

-                     Class (reserved=1056956KB, committed=7868KB)
                            (classes #1300)
                            (malloc=188KB #564) 
                            (mmap: reserved=1056768KB, committed=7680KB) 
Insured answered 26/6, 2015 at 14:27 Comment(4)
I think that you are showing us the Java Heap totals, not the MetaSpace totals.Adulteration
I removed Java Heap from the command resultsInsured
Where do you see that 1GB figure specifically relating to metaspace sizeHermes
I assume that because Classes are in Metaspace in Java 8. Am I not right?Insured
I
33

The reason why Java reserves 1G for Classes hides in the way how it manages compressed class pointers.

The long answer: read this doc https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/considerations.html

The short answer: setup the correct size in 'CompressedClassSpaceSize' property -XX:CompressedClassSpaceSize=300m

Insured answered 28/6, 2015 at 20:21 Comment(2)
I also liked this detailed explanation about why CompressedClassSpaceSize is a hard limit: stuefe.de/posts/metaspace/what-is-compressed-class-spaceFewness
BEWARE ... this answer might be wrong. If you are using a limited and small metaspace and the value of the metaspace is smaller than XX:CompressedClassSpaceSize then that option might be ignored and JVM might use the formula CompressedClassSpaceSize = MaxMetaspaceSize – 2 * InitialBootClassLoaderMetaspaceSizeIllustrational
H
4

Class (reserved=1221904KB

this isn't memory that's being used, just virtual address space

committed=197904KB

That's 197MB, not 1GB

Therefore you're not showing that java actually consumes 1GB of memory for class data, only that it reserves 1GB worth of address space.

Hermes answered 26/6, 2015 at 15:1 Comment(5)
Yes, you are right. That is what I meant. Sorry, English is not my native language. I'll edit the topic.Insured
But It should not reserve so much memory because I set up MetaspaceSize=300m and MaxMetaspaceSize=400m. Unpredictable reservation is bad. I have other JMV processes on that VM and I can't start them because there is no free memory.Insured
you can just turn on overcommit to allow it to reserve that much space.Hermes
This is a possible workaround. But I want to understand why java reserves 1G for Classes in the first place.Insured
I think that may have something to do with it needing a contiguous block of memory for compressed class space, which you are using. There's the CompressedClassSpaceSize option.Hermes

© 2022 - 2024 — McMap. All rights reserved.