Java 8 reserves minimum 1G for Metaspace despite (Max)MetaspaceSize
Solution 1
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
Solution 2
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.
Eugene To
Updated on June 29, 2020Comments
-
Eugene To almost 4 years
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)
-
Eugene To almost 9 yearsYes, you are right. That is what I meant. Sorry, English is not my native language. I'll edit the topic.
-
Eugene To almost 9 yearsBut 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.
-
the8472 almost 9 yearsyou can just turn on overcommit to allow it to reserve that much space.
-
Eugene To almost 9 yearsThis is a possible workaround. But I want to understand why java reserves 1G for Classes in the first place.
-
the8472 almost 9 yearsI 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. -
Andrei Damian-Fekete over 4 yearsI also liked this detailed explanation about why CompressedClassSpaceSize is a hard limit: stuefe.de/posts/metaspace/what-is-compressed-class-space
-
Rafael over 2 yearsBEWARE ... 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 formulaCompressedClassSpaceSize = MaxMetaspaceSize – 2 * InitialBootClassLoaderMetaspaceSize