一次CMS GC的调优工作

简介:

某台机器的内存比较大,之前的JVM参数是4G的堆,在压测过程中发现当QPS上来以后,Full GC会开始抬头,YoungGC的频率就不用说了,比较高。

观察GC日志和jstat -gcutil,感觉是QPS在峰值的时候对象创建比较多,也有大对象产生。于是打算加大堆的大小来延缓GC的时机,并且有一些GC参数的优化,反复调整后找到了一个适合我们的参数(没有一个best的参数,还是得按照应用的的情况去测量,最好是一遍压测一遍调整,最终找到一个best fit的参数组)。

在把堆调大的过程中比较担心下面几个问题:

1、GC的压力会不会增大?

2、一次GC的耗时会不会增加?

3、如果在GC stop-the-world的时间里,rt飙高怎么办?

这些问题最终都得到了解答,参考CMS GC的原理,结合jstat的观察,有了如下的结论。

新生代扩大3倍后,YoungGC每次会从root开始寻找存活的引用,而增大内存其实并不会导致存活对象增多(死亡对象是会增加的),因为只要你的QPS和rt是稳定的,那么同时存在的线程数也是稳定的,一个线程对应一个request,一个request中生成的对象相对是固定的,也就是说,只要QPS和rt稳定,只要内存足够,调的更大,其实正在处理的请求中的对象还是那么多,一次扫描的时间是不会明显增长的,所以往s0和s1拷贝的对象空间也是不会明显增长的,这导致YoungGC的开销和时间,其实并不会像配置的参数那样成倍增长。

而实际上,通过加大新生代的大小,YoungGC的频率明显减小,因为YoungGC是要stop-the-world的,所以应用停机的时间也会缩短。

旧生代的内存增大,可以避免QPS比较高时,内存迅速占满OldGen,触发Full GC。而对于CMS GC而言,因为上面说的新生代live对象不会明显增长,对remark阶段的耗时也是不会增长太多的,而CMS GC的sweep阶段是并发的,通过jstat可以看到Old区的占用百分比是慢慢减少的,sweep的过程对应用的rt影响不明显。

另外加入了-XX:+CMSScavengeBeforeRemark这个参数,用于在remark之前先做一次YoungGC,目的也是为了减少remark的时间,毕竟remark是要stop-the-world的。

目录
相关文章
|
5月前
|
算法 Java
jvm性能调优 - 15JVM的老年代垃圾回收器CMS的缺点
jvm性能调优 - 15JVM的老年代垃圾回收器CMS的缺点
112 0
|
3月前
|
监控 Java 测试技术
JVM 性能调优 及 为什么要减少 Full GC
JVM 性能调优 及 为什么要减少 Full GC
108 4
|
18天前
|
监控 Java Perl
使用jstat工具来监控G1垃圾回收器的性能
使用jstat工具来监控G1垃圾回收器的性能
|
5月前
|
存储 分布式计算 前端开发
jvm性能调优实战 - 26一个每秒10万并发的系统如何频繁发生Young GC的
jvm性能调优实战 - 26一个每秒10万并发的系统如何频繁发生Young GC的
130 0
|
5月前
|
存储 Java
jvm性能调优实战 - 23 模拟Young GC的发生及分析GC日志
jvm性能调优实战 - 23 模拟Young GC的发生及分析GC日志
100 0
|
11月前
|
缓存 算法 Java
JVM CMS GC算法解析
JVM CMS GC算法解析
77 0
|
算法 Java
21-看懂CMS收集器工作机制
年轻代垃圾回收器机制我们都很清楚了,接下来我们介绍最核心的老年代垃圾回收环节。
119 0
21-看懂CMS收集器工作机制
|
前端开发 Java
Java虚拟机 CMS GC 调优解析
随着 JDK 版本的不断升级,其 GC 策略也随之不停革新,从早期的 1.4 到如今的 11(本文仅讨论在线上环境落地规模较大的版本),其对应的 GC 策略也随之由 Serial、Parallel、CMS 演进至当前的 G1 甚至即将落地的 ZGC 。每一次的调整无不是基于环境的适配性以及业务场景特性,无论如何,只要能够基于特定的操作系统内核、物理内存、JDK版本以及业务特性,达到收益最大化,采用何种实现策略都不为过。当然,还是建议大家以官方的推荐为准,基于自己的业务场景进行不断优化调整,这样才能保证万无一失,使得我们的业务能够健康发展。
154 0
|
存储 缓存 算法
详述JVM的GC及垃圾回收策略
详述JVM的GC及垃圾回收策略
917 2
详述JVM的GC及垃圾回收策略
|
Java
JVM GC频繁优化
JVM GC频繁优化
192 0