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)
In Java 8 and onwards, we can set the initial and maximum size of Metaspace using the following commands: -XX:MetaspaceSize=N - sets the initial (and minimum size) of the Metaspace. -XX:MaxMetaspaceSize=N - sets the maximum size of the Metaspace.
The default size of -XX:MetaspaceSize is platform-dependent and ranges from 12 MB to about 20 MB.
MetaSpace grows automatically by default. Here, the garbage collection is automatically triggered when the class metadata usage reaches its maximum metaspace size. It is removed from java 8. It is introduced in Java 8.
Simply put, Metaspace is a new memory space – starting from the Java 8 version; it has replaced the older PermGen memory space. The most significant difference is how it handles memory allocation. Specifically, this native memory region grows automatically by default.
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With