本文以jdk8为例进行Java进程内存说明,与其他jdk版本存在一些差异。
Java进程内存分为jvm管理内存和非jvm管理内存。jvm管理内存又分为堆内存和非堆内存。
堆内存会分为年轻代和老年代,年轻代又会分为Eden区、Survivor0区(S0)、Survivor1区(S1)。
最大堆内存通过 -Xmx 限制,初始堆内存通过 -Xms 配置,年轻代通过 -Xmn 限制,老年代=Xmx - Xmn。
如果Xmn不设置,则通过 -XX:NewRatio来计算,NewRatio默认是2,不允许小于1。
NewRatio=老年代/年轻代,如果NewRatio=2,则表示老年代是年轻代的2倍,即年轻代占Xmx的1/3。
Eden、S0、S1的大小则通过 -XX:SurvivorRatio参数来控制
Eden : S0 = SurvivorRatio
Eden = Xmn / (SurvivorRatio + 2) * SurvivorRatio
S0 = S1 = Eden / SurvivorRatio = Xmn / (SurvivorRatio + 2)
非堆内存主要有线程的内存、元空间、CompressedClassSpace、CodeCache和DirectByteBuffer申请的堆外内存。
线程数量 * Xss 就可以知道线程占用的内存大小,Xss默认是1M。
如果不确定Xss值是多少,可以执行jinfo -flag ThreadStackSize <pid>
元空间默认最大值是机器最大内存,可以通过 -XX:MaxMetaspaceSize 参数修改。元空间包含类结构、方法与字节码、类字段描述、常量池等。
这块内存是在开启压缩类指针的情况下,类结构使用的内存空间。
可以通过 -XX:CompressedClassSpaceSize配置CompressedClassSpace的内存最大值,CompressedClassSpace默认值是1G,大小范围是:1M~3G。
在开启压缩类指针的情况下(堆内存不超过32G的时候,默认开启),Metaspace是包含CompressedClassSpace的,CompressedClassSpace大小和MaxMetaspaceSize大小有关系。
如下图,图中的Klass就是CompressedClassSpace
由于Metaspace包含CompressedClassSpace,所以当CompressedClassSpaceSize>=MaxMetaspaceSize时,CompressedClassSpaceSize需要用下面公式重新计算,InitialBootClassLoaderMetaspaceSize默认是4M
CompressedClassSpaceSize =
MaxMetaspaceSize - 2*InitialBootClassLoaderMetaspaceSize
不开启压缩类指针的情况下,CompressedClassSpace独立于Metaspace 。
用 jcmd <pid> GC.heap_info
命令看下区别:
Metaspace包含CompressedClassSpace:
Metaspace不包含CompressedClassSpace,Metaspace里看不到class space:
JVM会将字节码编译为本地机器码,使用CodeCache来保存。CodeCache默认最大是240M,可以通过 -XX:ReservedCodeCacheSize 参数修改最大值。
NIO的DirectByteBuffer API申请的内存。
通过 -XX:MaxDirectMemorySize参数限制这块内存大小
非jvm管理的内存则是由java进程申请,但是不在jvm监控的内存,通过jmap分析不到的内存。比如,PageCache、Zip工具使用的内存。
虽然DirectByteBuffer申请的内存不能直接分析到,但是可以通过堆内DirectByteBuffer对象分析到这块内存,也可以限制这块内存的最大值,所以DirectByteBuffer不属于这个范畴。
《聊聊jvm的CompressedClassSpace》[https://cloud.tencent.com/developer/article/1408827]
《What is Compressed Class Space?》[https://stuefe.de/posts/metaspace/what-is-compressed-class-space/]
《is-compressedclassspacesize-area-contains-maxmetaspacesize-area》[https://stackoverflow.com/questions/54250638/is-compressedclassspacesize-area-contains-maxmetaspacesize-area]