如何了解CMS的垃圾碎片率

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何了解CMS的垃圾碎片率相关的知识,希望对你有一定的参考价值。

参考技术A

PrintFLSStatistics这个参考比较有用,因为CMS GC会有碎片问题,而随着碎片的越来越严重,GC性能会变差直到发生FullGC,而FullGC时STW通过会超过数秒,这对OLTP系统来说是致命的,通过这个参数可以在gc日志中输出free list方式分配内存后内存统计情况和碎片情况;

从CompactibleFreeListSpace的描述可知CMS使用free list分配内存
-- 源码摘自compactibleFreeListSpace.hpp:

再看compactibleFreeListSpace.cpp中的 gc_prologue 和 gc_epilogue (prologue的中文意思是开场白,epilogue的中文意思是收场白,所以这两个方法可以理解为gc前和gc后),由两个方法的实现可知,如果JVM参数PrintFLSStatistics 不为0(负数也可以),那么每次GC前后都会调用reportFreeListStatistics()方法打印出free list的统计信息:

再看reportFreeListStatistics的具体实现,分为两个部分来看:

输出free list统计信息,gc日志中输出内容如下:
Total Free Space: 25165824
Max Chunk Size: 25165824
Number of Blocks: 1
Av. Block Size: 25165824
Tree Height: 1

如果JVM参数为PrintFLSStatistics 大于1,例如 -XX:PrintFLSStatistics=2 ,那么还会输出IndexedFreeLists的统计信息,以及如下的gc日志,能够直观的看到碎片率,frag的值越大碎片化越严重,JVM的初始化时frag的值为0.0000,即没有任何碎片:

为了查询碎片化率越来越严重的GC日志,笔者基于kafka 2.11-1.1.1版本,对其GC参数进行了一些调整,从而引起不断CMS GC:

接下来只需要启动一个kafka broker,然后利用kafka自带的压测脚本向broker发送1kw条消息(每条消息128个字节):
bin/kafka-run-class.sh org.apache.kafka.tools.ProducerPerformance --topic topic-afei-test --num-records 10000000 --record-size 128 --throughput -1 --producer-props acks=1 bootstrap.servers=127.0.1.168:9092 buffer.memory=67108864 batch.size=8196

由jstat可知,FGC非常严重,每2s就有好几次的FGC:

再看gc日志,kafka默认开启了gc日志(位于:logs/kafkaServer-gc.log.0.current):

使用CMS垃圾收集器产生的问题和解决方案

原始数据

https://juejin.im/post/5d8c5a5de51d4578323d51bd

 

参考链接

https://my.oschina.net/hosee/blog/674181

方案小结

1.晋升数据并不大,但是碎片化老年代无法满足空间分配,可以通过设置固定次数的 gc ,添加一次空间整理,此外还可以调大年轻代 from、to 的空间,保证朝生夕灭的数据在年轻代就被回收;

2.晋升数据较大,但是老年代剩余空间不足无法分配,可以通过调小触发老年代 gc 的阈值,实现空间清理;

 

参数设置

https://www.cnblogs.com/buwuliao/p/10646177.html

 

cms 实现的方法论

https://hllvm-group.iteye.com/group/topic/38223

以上是关于如何了解CMS的垃圾碎片率的主要内容,如果未能解决你的问题,请参考以下文章

CMS垃圾回收器

记一次Redis的内存碎片比过高的解决

对线面试官CMS垃圾回收器

CMS垃圾回收机制

CMS 和G1 的区别

碎片垃圾收集