尽管(Max)MetaspaceSize,Java 8仍为Metaspace保留最小1G

Eug*_* To 25 java jvm jvm-hotspot jvm-arguments

Java 8在启动后为Metaspace预留了1G.这意味着最小元空间大小为1G.但我将MetaspaceSize设置为300米,将MaxMetaspaceSize设置为400米.为什么Java会保留更多,然后我允许?

Java版本

$ 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)
Run Code Online (Sandbox Code Playgroud)

VM标志

$ 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 
Run Code Online (Sandbox Code Playgroud)

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) 
Run Code Online (Sandbox Code Playgroud)

就在开始之后

Total: reserved=2402748KB, committed=150796KB     

-                     Class (reserved=1056956KB, committed=7868KB)
                            (classes #1300)
                            (malloc=188KB #564) 
                            (mmap: reserved=1056768KB, committed=7680KB) 
Run Code Online (Sandbox Code Playgroud)

Eug*_* To 27

Java为类保留1G的原因隐藏了它管理压缩类指针的方式.

答案很长:阅读本文档 https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/considerations.html

简短的回答:在'CompressedClassSpaceSize'属性中设置正确的大小-XX:CompressedClassSpaceSize = 300m

  • 我也喜欢这个关于为什么 CompressedClassSpaceSize 是硬限制的详细解释:https://stuefe.de/posts/metaspace/what-is-compressed-class-space/ (2认同)