Jvm g1调整
1.升级jdk8过程
1.使用运维工具jdk升级,(升级失败,需要重新申请机器);
2.修改启动脚本 相关参数start.sh;
3.摘除线上流量后,更新配置重启应用;
4.恢复线上流量观察jvm;
2.调优目标
是为c端流量提供基础服务的,调优第一目标是低延迟,第二目标是提高吞吐量;
3.jvm启动相关配置参数解读:
OPTS_MEMORY="-server
-Xms6G ##jvm内存最大值
-Xmx6G ##jvm内存最大可用内存
-XX:MetaspaceSize=256M ##
-XX:MaxMetaspaceSize=256M
-XX:+UseG1GC
-verbose:gc
-Xloggc:/export/Logs/pi-work.123.local/pi-work-jvm.log
-XX:+PrintGCDetails ##打印详细gc日志
-XX:+PrintGCDateStamps ##打印gc时间戳
-XX:+PrintHeapAtGC ##gc前和gc后打印堆信息
-XX:+PrintGCApplicationConcurrentTime ##应用程序在不停止的情况下工作的时间,即两个连续安全点之间的时间.
-XX:+PrintGCApplicationStoppedTime ##显示应用程序在安全点停止的时间.大多数情况下,安全点是由垃圾收集的世界各个阶段引起的
-XX:+PrintTenuringDistribution ##输出显示在survivor空间里面有效的对象的岁数情况
-XX:+UnlockExperimentalVMOptions ##解锁实验参数
-XX:+UnlockDiagnosticVMOptions ##解锁诊断参数 G1SummarizeRSetStats
-XX:+G1PrintRegionLivenessInfo ##打印在清除阶段每个Region存活对象信息。
-XX:+G1SummarizeRSetStats ##可以确定并发优化线程是否能够及时处理更新日志缓冲区
-XX:+PrintAdaptiveSizePolicy ##可以开启打印启发式算法决策细节
-XX:+PrintReferenceGC ##个参数会打印各种引用的处理时间
-XX:ParallelGCThreads=4 ##gc线程数------------一般配置成和机器核数相等
-XX:G1HeapRegionSize=32M ##每个regions大小-------------2,4,8,16,32 其他参数不生效;
-XX:G1MaxNewSizePercent=90 ##年轻代占比最大空间-------------,Eden区和Survior区的大小之和接近 -XX:G1MaxNewSizePercent,这个时候就要考虑调大 -XX:G1MaxNewSizePercent 。
-XX:MaxGCPauseMillis=150 ##gc最大停顿时间------------当发现eden区分配过少,可以适当提升该配置(年轻代提升可以有效减少yanggc次数)
-XX:InitiatingHeapOccupancyPercent=10 -XX:G1HeapWastePercent=1 ##堆废百分比达到参数值时,停止混合回收-------混合收集时间过长时,可以降低该参数
-XX:G1MixedGCLiveThresholdPercent=85 默认值为85%存活对象超过region的百分之85,不会混合回收,也就是说 有可能造成15的空间浪费;
-XX:SoftRefLRUPolicyMSPerMB=50 默认值为200
3.G1配置参数调整过程中遇到的问题:
1 old区占用比例持续增长:
发生old区占用比例持续增长的原因有很多,可以通过日志分析看是下面那些原因造成的:
- 软引用对象使用较多 rerefrence,可以尝试降低以下参数:
-XX:SoftRefLRUPolicyMSPerMB=50
2.弱引用对象回收耗时占比高(ThreadLocal)
-XX:+ParallelRefProcEnabled #启用弱引用对象的并行回收
3.混合回收的频率低,可以尝试调整以下参数:
-XX:InitiatingHeapOccupancyPercent=10 # 当老年代占比达到堆大小10%
时,下一次gc触发混合回收;
- 空间碎片率较高,降低以下参数:
-XX:G1MixedGCLiveThresholdPercent=85 默认值为85%存活对象超过region的百分之85,不会混合回收,也就是说 有可能造成15的空间浪费
- 大对象区会被jvm监控计入old ,适当调大region区域:(需要分析)
-XX:G1HeapRegionSize=32M ##每个regions大小-------------2,4,8,16, 32 其他参数不生效;
以下日志,表示大对象引起的混合回收;
注意:
1.Worker.定时的频率尽量要小于yanggc的频率; 否则定时的产生的垃圾会影响yangGc的效率;
2.在 JDK8u40 之前的版本即便大对象区间是完全空闲的,也只会在井行回收循环的清除暂停阶段才会回收大对象。而JDK8u40 之后,新增了年轻代、Full GC 段针对大对象区间的回收功能,只要大对象区间不再包含任何引用,这些区间就会被回收井且放入空闲区间队列。即年轻代回收、并行回收循环、Full GC ,它们都会参与到大对象区间的回收工作。
2 压测并发较大的时候发生cpu飙升异常:
gc太频繁造成的,操作是提高以下参数,降低混合回收频率:-XX:InitiatingHeapOccupancyPercent=10 # 当老年代占比达到堆大小10%时,下一次gc触发混合回收;
jvm日志搜索 mix 可以发现G1HeapWastePercent应该调整成2最为合适;
-XX:G1HeapWastePercent=2
,
3主要目的是尽量减少stw
yangGC和fullgc都会存在stw,
yangGC时间可控,但是fullgc时间不可控制,风险最大,
所以调优总目标就是消灭fullgc,并且在保证每次停顿时间可以接受的前提下,尽量减少yangGC的次数(他们总是成反比);
G1模拟下主要有四种回收方式:
Young GC:所有Eden区域满了后触发,并行收集,且完全STW。
并发标记周期:它的第一个阶段初始化标记和YGC一起发生,这个周期的目的就是找到回收价值最大的Region集合(垃圾很多,存活对象很少),为接下来的Mixed GC服务。Mixed
Mixed GC:回收所有年轻代的Region和部分老年代的Region,Mixed GC可能连续发生多次。
Full GC:非常慢,对OLTP系统来说简直就是灾难,会STW且回收所有类型的Region。
YGC:是频率最高的gc
G1垃圾收集过程(yangGc和fullGC的过程类似):
1、初始标记
仅仅是标记GC Roots能直接关联的对象,速度很快。stop the word。
2、并发标记
从GC Roots出发,对堆中对象进行可达性分析,找出存活对象,该阶段耗时较长,但是可与用户线程并发执行。
3、最终标记
主要修正在并发标记阶段因为用户线程继续运行而导致标记记录产生变动的那一部分对象的标记记录。stop the word。
4、筛选阶段
将各个region分区的回收价值和成本进行排序,根据用户所期望的停顿时间制定回收计划。这阶段停顿用户线程。stop the word。
G1调整优化效果:
Tp99更加平稳:
Tp999提升明显: