这里是weihubeats ,觉得文章不错可以关注公众号小奏技术,文章首发。拒绝营销号,拒绝标题党
背景
在上次记一次RocketMQ线上broker内存持续升高问题排查
之后得出了一个结论
JKD8 G1在经历一次Full GC后就会归还内存给操作系统
实际最近也在做RocketMQ
缩容的事情,所以打算在线上验证一下
jvm启动参数
java
-Xms46g -Xmx46g -XX:MetaspaceSize=1259m -XX:MaxMetaspaceSize=2517m -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:SoftRefLRUPolicyMSPerMB=0 -verbose:gc -Xloggc:/dev/shm/rmq_srv_gc_%p_%t.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m -XX:-OmitStackTraceInFastThrow -XX:-UseLargePages
这里还是把我们的jvm参数贴出来,需要注意的是我们的设置-Xms
和-Xmx
设置的是一样大小
验证
手动Full GC
由于线上的内存比较大,达不到出发Full GC
的情况,所以我们决定手动触发Full GC
试试
这样手动
Full GC
对线上服务可能会有影响,我这里的broker
是已经停写了,所以无需担心
手动Full GC
命令
sh
jcmd pid GC.run
使用jcmd
+进程的pid即可手动触发Full GC
如何验证是否已经触发了Full GC
呢。我们还是使用jstat
查看
验证是否Full GC
yaml
jstat -gc -h10 29134 1000 200
yaml
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
0.0 32768.0 0.0 32768.0 23265280.0 12664832.0 24936448.0 13944095.5 146176.0 120498.3 0.0 0.0 115074 1014.061 0 0.000 1014.061
0.0 32768.0 0.0 32768.0 23265280.0 13058048.0 24936448.0 13944095.5 146176.0 120498.3 0.0 0.0 115074 1014.061 0 0.000 1014.061
0.0 32768.0 0.0 32768.0 23265280.0 13385728.0 24936448.0 13944095.5 146176.0 120498.3 0.0 0.0 115074 1014.061 0 0.000 1014.061
0.0 32768.0 0.0 32768.0 23265280.0 13811712.0 24936448.0 13944095.5 146176.0 120498.3 0.0 0.0 115074 1014.061 0 0.000 1014.061
0.0 32768.0 0.0 32768.0 23265280.0 14237696.0 24936448.0 13944095.5 146176.0 120498.3 0.0 0.0 115074 1014.061 0 0.000 1014.061
0.0 32768.0 0.0 32768.0 23265280.0 14614528.0 24936448.0 13944095.5 146176.0 120498.3 0.0 0.0 115074 1014.061 0 0.000 1014.061
0.0 32768.0 0.0 32768.0 23265280.0 14991360.0 24936448.0 13944095.5 146176.0 120498.3 0.0 0.0 115074 1014.061 0 0.000 1014.061
0.0 32768.0 0.0 32768.0 23265280.0 15319040.0 24936448.0 13944095.5 146176.0 120498.3 0.0 0.0 115074 1014.061 0 0.000 1014.061
0.0 32768.0 0.0 32768.0 23265280.0 15663104.0 24936448.0 13944095.5 146176.0 120498.3 0.0 0.0 115074 1014.061 0 0.000 1014.061
0.0 32768.0 0.0 32768.0 23265280.0 16072704.0 24936448.0 13944095.5 146176.0 120498.3 0.0 0.0 115074 1014.061 0 0.000 1014.061
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
0.0 32768.0 0.0 32768.0 23265280.0 16465920.0 24936448.0 13944095.5 146176.0 120498.3 0.0 0.0 115074 1014.061 0 0.000 1014.061
0.0 32768.0 0.0 32768.0 23265280.0 16646144.0 24936448.0 13944095.5 146176.0 120498.3 0.0 0.0 115074 1014.061 1 0.000 1014.061
0.0 32768.0 0.0 32768.0 23265280.0 16646144.0 24936448.0 13944095.5 146176.0 120498.3 0.0 0.0 115074 1014.061 1 0.000 1014.061
0.0 0.0 0.0 0.0 30392320.0 737280.0 17842176.0 91377.7 62208.0 53680.3 0.0 0.0 115074 1014.061 1 2.236 1016.297
0.0 0.0 0.0 0.0 30392320.0 1146880.0 17842176.0 91377.7 62208.0 53680.3 0.0 0.0 115074 1014.061 1 2.236 1016.297
0.0 0.0 0.0 0.0 30392320.0 1556480.0 17842176.0 91377.7 62208.0 53680.3 0.0 0.0 115074 1014.061 1 2.236 1016.297
0.0 0.0 0.0 0.0 30392320.0 1982464.0 17842176.0 91377.7 62208.0 53680.3 0.0 0.0 115074 1014.061 1 2.236 1016.297
0.0 0.0 0.0 0.0 30392320.0 2326528.0 17842176.0 91377.7 62208.0 53680.3 0.0 0.0 115074 1014.061 1 2.236 1016.297
0.0 0.0 0.0 0.0 30392320.0 2654208.0 17842176.0 91377.7 62208.0 53680.3 0.0 0.0 115074 1014.061 1 2.236 1016.297
0.0 0.0 0.0 0.0 30392320.0 3112960.0 17842176.0 91377.7 62208.0 53680.3 0.0 0.0 115074 1014.061 1 2.236 1016.297
可以看到FGCT
变成了1
但是值得注意的是我们的操作系统使用内存并没有减少
也就是说Full GC
后并没有释放内存到操作系统。
为何不释放内存归还给操作系统
实际在设置JVM参数的时候都是推荐设置-Xms
和-Xmx
一样大,避免频繁的向操作系统申请内存和释放内存,提高效率
如果我们的参数比如设置为-Xms20G -Xmx48G
那么在Full GC
之后才会释放内存给到操作系统。
总结
所以总结来说JKD8 G1在经历一次Full GC后就会归还内存给操作系统的前提是-Xms
和-Xmx
参数设置大小不一致才会归还。如果设置一样大即使经历Full GC
也不会归还给到操作系统
至于验证下次有机会在线上再验证下吧,网上也有很多人都验证了,这里就不验证了