十分钟学会GC问题简单排查流程
背景
线上的Java服务经常会遇到内存回收不到而导致GC频繁发生,严重影响服务质量,那么遇到这种问题该如何排查?本文就是一个GC问题排查的简单系统性分析。
一、如何排查
1.日志监控平台
目前市面上大多数公司都接入了日志监控系统,比如Grafana,一般这些系统都会配置收集各个集群里面每个实例的JVM监控信息。所以在监控平台里面我们就可以看到这些实例的GC信息,并对GC进行报警设置。所以通过经验的增加,也许从日志监控平台就能快速发现问题所在。
2.命令jstat
通过一些自带的命令,登录上服务器去查看实时的GC情况。
2.1 jstat -gc
显示与GC相关的堆信息。包括Eden区、两个Survivor区、老年代、永久代等的容量、已用空间、GC时间合计等信息。
2.2 jstat -gcutil
显示内容与-gc基本相同,但输出主要关注已使用空间占总空间的百分比。
EC | Eden区的大小 |
EU | Eden区已使用的大小 |
S0C | 幸存者0区的大小 |
S1C | 幸存者1区的大小 |
S0U | 幸存者0区已使用的大小 |
S1U | 幸存者1区已使用的大小 |
MC | 元空间的大小 |
MU | 元空间已使用的大小 |
OC | 老年代的大小 |
OU | 老年代已使用的大小 |
CCSC | 压缩类空间的大小 |
CCSU | 压缩类空间已使用的大小 |
YGC | 从应用程序启动到采样时young gc的次数 |
YGCT | 从应用程序启动到采样时young gc消耗时间(秒) |
FGC | 从应用程序启动到采样时full gc的次数 |
FGCT | 从应用程序启动到采样时的full gc的消耗时间(秒) |
GCT | 从应用程序启动到采样时gc的总时间 |
2.3 总结
- 如果频繁发生YGC但很少发生FGC,说明在大量创建临时对象,然后又被回收掉了。
- 如果Old区域使用很高又频繁FGC,那说明内存泄漏了。(注意内存泄漏与内存溢出的区别)
需要更详细的关于JVM的命令可查看我的其他文章,在中有详细的介绍。
3. 堆内存分析
-
dump内存:使用jmap -dump命令将堆内存给下载出来
-
MAT分析:
-
打开Dominator Tree
-
分析内存最大对象
-
堆内存分析的工具有许多,熟悉一个使用即可。
二、总结
内存泄漏情况:一般发生这种,大多数都是因为能存活很久的对象引用了短生命周期的对象,导致短生命周期对象不能及时释放。
内存泄漏:程序在申请内存后,无法释放已经申请的内存。
内存溢出:程序在申请内存的时候,没有足够的内存空间供其使用。
这篇文章还是过于理论,但是博主作为24届毕业生实在没有遇到过线上发生GC的情况,如果遇到了应该也是老员工去处理,下次有幸参与排查的话,再重开一篇文章记录一下真实的GC排查过程。
#Java大厂如何面试##24届秋招同行攻略分享##我的实习求职记录##JVM##牛客在线求职答疑中心#