发布网友 发布时间:2022-12-10 22:08
共1个回答
热心网友 时间:2023-08-22 08:39
昨天 谢照东 大神在群里提出一个问题:怎么查看Metaspace里具体包含的是什么,起因是他的某个服务设置了 -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=512m ,但是通过 jstat -gcutil pid 查看 M 的值为98(M的=MU/MC),即Metaspace区的使用量达到了 512m*98% 。遗憾的是,这个推算是错误的;
以笔者测试环境上某个服务为例,配置了 -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m ,通过 jstat -gcutil pid 查看 M 的值为 98.32 ,即Meta区使用率也达到了 98.32% :
然后,再通过 jstat -gc 4210 2s 3 命名查看,结果如下图所示,计算MU/MC即Meta区的使用率确实达到了 98.32% ,但是MC,即Metaspace Capacity只有55296k,并不是参数 MetaspaceSize 指定的256m:
那么 -XX:MetaspaceSize=256m 的含义到底是什么呢?其实,这个JVM参数是指Metaspace扩容时触发FullGC的初始化阈值,也是最小的阈值。这里有几个要点需要明确:
笔者的环境,服务启动后,MU的值稳定在55296k,那么设置 -XX:MetaspaceSize=50m -XX:MaxMetaspaceSize=256m ,按照上面的推理,会发生一次CMS GC,事实也确实如此,部分gc日志如下所示:
JDK8+移除了Perm,引入了Metapsace,它们两者的区别是什么呢?Metasace上面已经总结了,无论 -XX:MetaspaceSize 和 -XX:MaxMetaspaceSize 两个参数如何设置,随着类加载越来越多不断扩容调整,直到MetaspaceSize(如果没有配置就是默认20.8m)触发FGC,上限是 -XX:MaxMetaspaceSize ,默认是几乎无穷大。而Perm的话,我们通过配置 -XX:PermSize 以及 -XX:MaxPermSize 来控制这块内存的大小,jvm在启动的时候会根据 -XX:PermSize 初始化分配一块连续的内存块,这样的话,如果 -XX:PermSize 设置过大,就是一种赤果果的浪费。很明显,Metapsace比Perm好多了^^;
JDK7 Perm 验证如下--设置 -XX:PermSize=64m -XX:MaxPermSize=64m ,那么PC初始化就是64m:
JVM源码分析之Metaspace解密