jvm调优
Posted xcrj
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jvm调优相关的知识,希望对你有一定的参考价值。
参考
应用需求
IO应用,计算应用
IO要求,低延迟应用,增加响应速度,减少暂停时间
比如一致诟病的android手机响应速度慢,指的是用户点击APP图表到应用程序打开,这段响应时间很长,需要着重减少单次GC的时间,不能在用户操作手机的过程中,一次GC的时间过长。
对于涉及大量用户操作的系统,对外提供接口的系统,IO要求都较高,都尽量要求响应速度,需要GC重点减少单次GC的时间,减少GC暂停时间
计算要求,高吞吐量应用,提高吞吐量
算法,重复创建对象,长时间存在的对象少
较大年轻代,较小的老年代,减少触发minor GC,单位时间内的暂停时间最短
对于AI等算法应用,其中涉及到大量计算,计算要求都较高,都尽量提高单位时间内计算线程运行的时间,需要GC重点减少单位时间内GC的时间,提高吞吐量
调优层次
架构调优(优先)
代码调优(优先)
JVM调优(其次)
数据库调优
操作系统调优
调优指标
GC频率,GC时间
GC频率,GC时间
时间(计算时间,IO时间),空间
吞吐量=应用线程运行时间/(应用线程运行时间+GC线程运行时间)
暂停时间:GC时工作线程被暂停的时间
内存占用:堆区内存大小
不可能三角,一款优秀的GC最多同时满足其中两项
- 吞吐量:单位时间内GC时间短
- 暂停时间:单次GC时间短
设计/使用GC时:
- 专注较大吞吐量或最小暂停时间
- 最大吞吐量和最小暂停时间的折衷
GC
GC | 串并行发 | 作用位置 | 算法 | 特点 | 场景 |
---|---|---|---|---|---|
Serial | 串行 | 新生代 | 复制算法 | 响应速度 | 单CPU环境下client模式 |
ParNew | 并行 | 新生代 | 复制算法 | 响应速度 | 多CPU环境下Server模式下与CMS配合使用 |
Parallel Scavenge | 并行 | 新生代 | 复制算法 | 吞吐量 | 多运算,少IO |
Serial Old | 串行 | 老年代 | 标记-整理 | 响应速度 | 单CPU环境下client模式 |
Parallel Old | 并行 | 老年代 | 标记-整理 | 吞吐量 | 多运算,少IO |
CMS | 并发 | 新生代,老年代 | 标记-清除 | 响应速度 | B/S业务 |
G1 | 并发,并行 | 新生代,老年代 | 复制算法、标记-整理 | 响应速度 | 服务端应用 |
ZGC | 新生代,老年代 | 复制算法 | 服务端应用 |
GC概念
概念 | 针对 | gc |
---|---|---|
young gc/minor gc | 年轻代的gc | |
old gc/major gc | 老年代gc | CMS |
full gc | 新生代、老年代、元空间gc | |
mixed gc | 年轻代、部分老年代gc | G1 |
GC算法
标记-清除:
过程:最初的算法,先标记再清除
优点:基础算法
缺点:新生代大多数对象都是朝生夕死,死亡对象多,标记对象多,清除对象多,执行次数越多效率越低;
效率随对象数量增多而下降;产生大量外部碎片
使用:CMS使用该算法收集老年代的垃圾
标记-复制算法:
过程:内存分成两个区域,第1个区域使用完了,把幸存对象复制到第2个区域,再清空第1块内存
优点:主要应用于新生代
缺点:另一部分空间始终空闲;Eden区幸存对象无法放入s区,需要分配担保策略,直接进入老年代
使用:Serial、ParNew、Parallel
标记-整理
背景:标记-复制算法不适用与老年代存在大量幸存对象的情况
过程:往内存的一端移动,清理掉边界以外的内存
优点:解决标记-清除算法的外部碎片问题;解决标记-复制算法需要分配担保的问题
使用:Serial Old、Parallell Old
标记-清除:
标记-整理:
对比 标记-清除 和 标记-整理:
算法 | 移动 | 内存 |
---|---|---|
标记-清除 | 对象不移动 | 内存分配复杂 空间碎片化,触发GC,对象分配依赖于“空闲列表”,对象分配阶段耗时 |
标记-整理 | 对象移动 | 内存回收复杂 老年代大部分对象存活,GC时伴随大量的对象移动,对象回收阶段耗时 |
GC/Serial, ParNew, Parallel
都关注新生代,都使用标记-复制算法,因为新生代大部分对象都死的快,需要复制的对象少,效率就高
GC/CMS, Serial Old, Parallel Old
都关注老年代,老年代大部分对象都存活,
使用标记-整理算法,内存分配时间短,回收时间长
使用标记-清除算法,内存分配时间长,回收时间短
GC/CMS
GC/G1
面向服务端应用,针对具有大内存、多处理器的机器,在普通大小的堆里表现并不惊喜
需要低GC延迟并有大堆的应用程序(G1“增量式清理”来保证每次GC停顿时间不会过长)
在堆大小约6GB或更大时,可预测的暂停时间可以低于0.5秒
转移阶段要处理所有存活的对象,耗时会较长。因此,G1停顿时间的瓶颈主要是标记-复制中的转移阶段STW。为什么转移阶段不能和标记阶段一样并发执行呢?主要是G1未能解决转移过程中准确定位对象地址的问题。
与ZGC对比,G1的转移阶段完全STW的,且停顿时间随存活对象的大小增加而增加。
GC/ZGC
JDK11
停顿时间不超过10ms
停顿时间不会随着堆的大小,或者活跃对象的大小而增加
支持8MB~4TB级别的堆(未来支持16TB)
转移阶段也是并发执行的
ZGC几乎所有暂停都只依赖于GC Roots集合大小,停顿时间不会随着堆的大小或者活跃对象的大小而增加。与ZGC对比,G1的转移阶段完全STW的,且停顿时间随存活对象的大小增加而增加。
jdk/GC
jdk各个版本默认GC
jdk版本 | 默认GC | 新生代GC | 老年代GC |
---|---|---|---|
jdk7u4- | Parallel Scavenge + Serial Old | Parallel Scavenge | Serial Old |
jdk7u4+ | Parallel Scavenge + Parallel Old | Parallel Scavenge | Parallel Old |
jdk8 | Parallel Scavenge + Parallel Old | Parallel Scavenge | Parallel Old |
jdk11 | G1 | G1 | G1 |
jdk17 | 默认GC | 新生代GC | 老年代GC |
jdk21 | 默认GC | 新生代GC | 老年代GC |
jvm参数对应gc
参数 | 代表GC |
---|---|
-XX:-UseSerialGC | Serial + Serial Old |
-XX:-UseParNewGC | ParNew + Serial Old |
-XX:-UseParallelGC | Parallel Scavenge + Serial Old |
-XX:-UseParallelOldGC | Parallel Scavenge + Parallel Old |
-XX:-UseConcMarkSweepGC | CMS + ParNew |
-XX:-UseG1GC | G1 |
参数 | 代表GC |
jdk7/GC
命令:java -XX:+PrintCommandLineFlags -version
结果:-XX:+UseParallelGC
JDK 7u4-
- server模式默认采用 Parallel Scavenge + Serial Old(PS MarkSweep)
- 新生代用 Parallel Scavenge 老年代用 Serial Old
JDK 7u4=+
- server模式默认采用 Parallel Scavenge + Parallel Old(PS MarkSweep)
- 新生代用 Parallel Scavenge 老年代用 Parallel Old
jdk8/GC
server模式默认采用 Parallel Scavenge + Parallel Old(PS MarkSweep)
新生代用 Parallel Scavenge 老年代用 Parallel Old
jdk11/GC
命令:java -XX:+PrintCommandLineFlags -version
结果:-XX:+UseG1GC
server模式默认采用 G1
jdk17/GC
jdk21/GC
调整
堆
-Xms 等于 -Xmx 建议扩大3-4倍FullGC后老年代空间大小
过小:频繁GC
过大:GC时间过长
堆/新生代
-Xmn,1-1.5倍FullGC之后的老年代空间占用
过小:minor GC次数频繁;对象直接进入老年代,触发Full GC时工作线程被暂停的时间
过大:老年代变小,Full GC频繁执行;minor GC增加回收时间
堆/老年代
老年代使用并发收集器
方法区/元空间
-XX:MetaspaceSize 等于 -XX:MaxMetaspaceSize
1.2-1.5倍 Full GC后的元空间占用
调优过程
生成GC日志/dump文件/第三方可视化工具
分析判断
参数设置合理性
异常信息
GC频率
GC耗时,GC超过1秒,必须优化
吞吐量或响应时间异常
堆/老年代 持续上涨
确定目标
使用最小的硬件消耗来承载更大的吞吐量和更低的响应时间
- 堆内存使用率 <=70%
- 老年代内存使用率 <=70%
- 平均停止时间 <=1s
- Full GC调用次数接近于0 或 两次GC时间间隔>=24h
调整参数
调优工具
jps
以上是关于jvm调优的主要内容,如果未能解决你的问题,请参考以下文章