JVM性能优化-GC

973 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第31天,点击查看活动详情

概要

这里以G1垃圾收集器调优为例。

是否选用G1

官网 :藏宝图

150%以上的堆被存活对象占用2)对象分配和晋升的速度变化非常大

(3)垃圾回收时间比较长

G1调优

(1)使用G1GC垃圾收集器: -XX:+UseG1GC

修改配置参数,获取到gc日志,使用GCViewer分析吞吐量和响应时间

ThroughputMin PauseMax PauseAvg PauseGC count
99.16%0.00016s0.0137s0.00559s12

(2)调整内存大小再获取gc日志分析

-XX:MetaspaceSize=100M

-Xms300M

-Xmx300M

比如设置堆内存的大小,获取到gc日志,使用GCViewer分析吞吐量和响应时间。

ThroughputMin PauseMax PauseAvg PauseGC count
98.89%0.00021s0.01531s0.00538s12

(3)调整最大停顿时间

-XX:MaxGCPauseMillis=200 设置最大GC停顿时间指标。

比如设置最大停顿时间,获取到gc日志,使用GCViewer分析吞吐量和响应时间。

ThroughputMin PauseMax PauseAvg PauseGC count
98.96%0.00015s0.01737s0.00574s12
(4)启动并发GC时堆内存占用百分比
-XX:InitiatingHeapOccupancyPercent=45

G1用它来触发并发GC周期,基于整个堆的使用率,而不只是某一代内存的使用比例。值为 0 则表示“一直执行GC循环)'. 
默认值为 45 (例如, 全部的 45% 或者使用了45%).

比如设置该百分比参数,获取到gc日志,使用GCViewer分析吞吐量和响应时间。

ThroughputMin PauseMax PauseAvg PauseGC count
98.11%0.00406s0.00532s0.00469s12

G1调优最佳实战

官网 :藏宝图

(1)不要手动设置新生代和老年代的大小,只要设置整个堆的大小

why:blogs.oracle.com/poonam/incr…

G1收集器在运行过程中,会自己调整新生代和老年代的大小

其实是通过adapt代的大小来调整对象晋升的速度和年龄,从而达到为收集器设置的暂停时间目标

如果手动设置了大小就意味着放弃了G1的自动调优

(2)不断调优暂停时间目标

一般情况下这个值设置到100ms或者200ms都是可以的(不同情况下会不一样),但如果设置
成50ms就不太合理。暂停时间设置的太短,就会导致出现G1跟不上垃圾产生的速度。最终退
化成Full GC。所以对这个参数的调优是一个持续的过程,逐步调整到最佳状态。暂停时间
只是一个目标,并不能总是得到满足。

(3)使用-XX:ConcGCThreads=n来增加标记线程的数量

IHOP如果阀值设置过高,可能会遇到转移失败的风险,比如对象进行转移时空间不足。如果
阀值设置过低,就会使标记周期运行过于频繁,并且有可能混合收集期回收不到空间。

IHOP值如果设置合理,但是在并发周期时间过长时,可以尝试增加并发线程数,调高
ConcGCThreads。

(4)MixedGC调优

-XX:InitiatingHeapOccupancyPercent

-XX:G1MixedGCLiveThresholdPercent

-XX:G1MixedGCCountTarger

-XX:G1OldCSetRegionThresholdPercent

(5)适当增加堆内存大小

(6)不正常的Full GC

有时候会发现系统刚刚启动的时候,就会发生一次Full GC,但是老年代空间比较充足,一般是由Metaspace区域引起的。可以通过MetaspaceSize适当增加其大家,比如256M。

CPU占用率高

(1)top

(2)top -Hp PID

查看进程中占用CPU高的线程id,即tid

(3)jstack PID | grep tid