4年前 (2020-09-08)  爪哇岛 |   抢沙发  7513 
文章评分 0 次,平均分 0.0

metaspace gc 案例

这是我使用jvm的g1垃圾回收在GC时遇到的问题:

2400.241: [GC concurrent-root-region-scan-start]
2400.241: [Full GC (Metadata GC Threshold) 2400.252: [GC concurrent-root-region-scan-end, 0.0101404 secs]
2400.252: [GC concurrent-mark-start]
 1151M->603M(4356M), 2.6980537 secs]
   [Eden: 0.0B(2558.0M)->0.0B(2613.0M) Survivors: 55.0M->0.0B Heap: 1151.7M(4356.0M)->603.6M(4356.0M)], [Metaspace: 259187K->92248K(1034240K)]
 [Times: user=3.92 sys=0.00, real=2.70 secs]

这需要很长时间,每20-30分钟,metaspace就会触发一次完整的gc。

我的jvm metaspce元空间大小配置参数如下:

"-XX:MaxMetaspaceSize=768M",
"-XX:MetaspaceSize=256M"

每次它达到256M时,就会触发一次完整的full gc。

当它到达这个第一个高水位线时,它是否应该在下次达到最大内存之前使它变大?另外,metaspace上的gc会触发old gen老年代上的完整gc吗?

这使得p99的响应时间比我预期的要高。

 

分析原因

我的理解是元空间本身并不是每次被垃圾收集的。相反,堆中的对象包含对元空间对象的特殊引用。当GC收集对象时,相应的元空间对象将被释放。(从概念上讲,它类似于终结,终结器释放元空间对象。)

当它到达这个第一个高水位线时,它是否应该在下次达到最大尺寸之前使它变大?

显然不是。热点收集器的常规策略如下:

  1. 分配对象,直到达到当前堆限制
  2. 运行收集器
  3. 查看回收了多少空间,如果有必要,可以增加(或减少)堆大小。

这里似乎也采用了同样的策略。而完整的GC会导致足够的元空间被回收,从而决定不需要扩展元空间。

可以尝试将-XX:MetaspaceSize和-XX:MaxMetaspaceSize设置为相同的值,但这只会降低整个GCs的频率。

可以参考这篇文章介绍:https://javakk.com/369.html

metaspace元空间gc垃圾回收问题

当jvm上没有设置MaxMetaspaceSize属性时,什么条件触发Metaspace的垃圾回收?

假设我关闭几个未使用的类加载器,那么就有一个作用域来释放元空间内存中的内存。我的问题是,完整的gc是触发元空间内存的清理还是以其他方式触发的?

由于java8中默认的元空间是不受限制的,jvm何时知道需要从其元空间中清除未引用的类。

元空间本身不是垃圾回收的。但是java堆是。

什么时候java.lang.Class对象被收集,底层元数据也就被释放。所以在大多数情况下,如果有任何类可以卸载,那么常规GC循环也会释放元空间。

但是想知道何时触发gc来清理未部署的应用程序的元空间内存。

最迟在元空间的当前容量已满时,也可能是在常规垃圾回收卸载类时。

 

除特别注明外,本站所有文章均为老K的Java博客原创,转载请注明出处来自https://javakk.com/378.html

关于

发表评论

表情 格式

暂无评论

登录

忘记密码 ?

切换登录

注册