JVM-GC调优

作者: 石头耳东 | 来源:发表于2022-05-07 22:05 被阅读0次

零、本文纲要

一、 GC调优基本思路
二、 新生代内存调优
三、 老年代内存调优
四、 GC调优案例

官方GC调优指南

    1. 查看虚拟机运行参数

命令:"C:\Program Files\Java\jdk1.8.0_311\bin\java.exe" -XX:+PrintFlagsFinal -version | findstr "GC"

部分JDK8的JVM默认配置如下:

uintx GCTimeRatio                               = 99                                  {product}
uintx MaxGCPauseMillis                          = 4294967295                          {product}
uintx ParallelGCThreads                         = 13                                  {product}
 bool ScavengeBeforeFullGC                      = true                                {product}
 bool UseParallelGC                            := true                                {product}
 bool UseParallelOldGC                          = true                                {product}

一、 GC调优基本思路

1. 调优领域

内存
锁竞争
CPU占用
I/O

2. 目标确定

低延迟/高吞吐
低延迟:CMS、G1、ZGC
高吞吐:ParallelGC

3. 减少GC

查看Full GC前后的内存占用

  • ① 数据量是不是太多?

数据库查询limit

  • ② 数据表示是否太臃肿?

对象图
数据类型选择

  • ③ 是否存在内存泄漏?

软引用、弱引用
第三方缓存实现

二、 新生代内存调优

1. 新生代特点

① new操作内存分配廉价(TLAB thread-local allocation buffer)
② 新生代垃圾回收采用复制算法,回收代价低
③ 大部分对象用过即可回收
④ Minor GC的时间远低于Full GC

2. 新生代调优方法

  • ① 内存大小调整

命令:-Xmn size

Oracle建议新生代大小占整个堆空间25%-50%。

  • ② 新生代调优参考

Ⅰ 新生代能容纳所有[并发量 * (请求 - 响应)]的数据

Ⅱ 幸存区大到能保留[当前活跃对象 + 需要晋升对象]的数据

Ⅲ 晋升阈值配置得当,让长时间存货对象尽快晋升
-XX:+PrintTenuringDistribution:通过打印幸存区年龄空间数据,预估合理阈值
-XX:MaxTenuringThreshold=threshold:根据上述阈值,设置使用

三、 老年代内存调优

1. CMS老年代调优

注意:以CMS为例

  • ① CMS老年代内存越大越好

避免浮动垃圾过多,进而引起并发清除失败,退化为SerialOld。

  • ② 如果Full GC频繁,则先尝试调优新生代

  • ③ 观察发生Full GC时老年代内存占用,将老年代内存预设调大1/4~1/3

命令:-XX:CMSInitiatingOccupancyFraction=percent:当老年代内存使用占到老年代内存空间的68%(默认)触发Full GC。可以设置为75-80%。

四、 GC调优案例

案例一、 Full GC和Minor GC频繁

① 增大新生代内存大小
② 增大幸存区空间,以及晋升阈值

案例二、 请求高峰期发生Full GC,单次暂停时间特别长(CMS)

  • ① 确认哪个阶段时间较长:初始标记、并发标记、重新标记、并发清除

Ⅰ 初始标记:STW,标记GC Roots的直接关联对象
Ⅱ 并发标记:没有STW,使用GC Roots Tracing算法,进行跟踪标记。并发标记过程中产生变动的对象会放入一个队列中,供重新标记过程遍历使用。
Ⅲ 重新标记:STW,由于并发标记其他线程不暂停,可能产生新垃圾,重新标记
Ⅳ 标记清除:没有STW

  • ② 响应时间优先优化

命令:-XX:+CMSScavengeBeforeRemark

在重新标记之前,进行一次新生代的垃圾回收。可以减少重新标记的对象,提升效率,优化响应。

案例三、 老年代充裕情况下,发生Full GC(1.7)

永久代(元空间)空间不足导致的Full GC

五、结尾

以上即为JVM-GC调优的基础内容,感谢阅读。

相关文章

网友评论

    本文标题:JVM-GC调优

    本文链接:https://www.haomeiwen.com/subject/ifqfurtx.html