一、必要性
重要应用程序在使用过程中,忽然无法响应用户请求,排查发现网络联通无问题,gateway能够正常接收分发请求,应用进程正常,正常向注册中心发送请求,但是接收http请求全部返回报错。
添加gc后发现内存回收耗时太长,无法恢复。
二、定位问题
- 确定网络请求无问题。
- 进程正常。
- 打印gc报错信息,确定是否为gc回收问题。
2.1 gc回收问题定位
- 先查询本应用的内存使用情况:
jps -l 查询正在运行的所有应用
确认出问题应用的内存使用情况
top -p <PID> 在top界面中,你可以看到包括RES(常驻集大小,即进程当前使用的、未交换出的物理内存大小)和%MEM(进程使用的物理内存百分比)在内的内存相关统计信息。
jmap -heap pid 查看堆使用情况
jstat -gc pid 1000相隔一秒输出一次内存使用情况
- 查看较长时间的gc情况需要在启动文件中新增参数
GC_PRINT="-XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -XX:+PrintGCApplicationStoppedTime -XX:+PrintReferenceGC -Xloggc:./gclog/$APP_NAME-gc-%t.log"
GC日志输出参数
-XX:+PrintGC | 输出GC日志 |
-XX:+PrintGCDetails | 输出GC的详细日志 |
-XX:+PrintGCTimeStamps | 输出GC的时间戳(以基准时间的形式) |
-XX:+PrintGCDateStamps | 输出GC的时间戳(以日期的形式,如 2013-05-04T21:53:59.234+0800) |
-XX:+PrintHeapAtGC | 在进行GC的前后打印出堆的信息 |
-Xloggc:.../logs/gc.log | 日志文件的输出路径 |
- 堆使用情况
-
已经出现问题后:jmap -dump:live,format=b,file=dump.hprof PID
输出dump.hprof进行分析 -
已重启解决,需要跟进问题,启动参数添加:
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./gclog/$APP_NAME-gc-%t.log -XX:+HeapDumpBeforeFullGC
参数解释:
参数 | 解释 |
---|---|
-XX:+HeapDumpOnOutOfMemoryError | 参数表示当JVM发生OOM时,自动生成DUMP文件 |
-XX:HeapDumpPath=${目录} | 参数表示生成DUMP文件的路径,也可以指定文件名称 |
-XX:+HeapDumpBeforeFullGC | 当 JVM 执行 FullGC前 |
-XX:+HeapDumpAfterFullGC | 当 JVM 执行 FullGC后 |
三、gc工具
3.1 gc日志分析工具
- 在线分析工具https://gceasy.io/
GCEasy是一款在线的GC(垃圾收集)日志分析器,它可以用于分析JVM(Java虚拟机)的垃圾回收日志,提供可视化的分析结果和建议。GCEasy具有内置的智能功能,能够自动检测JVM和Android GC日志中的问题,并为之推荐解决方案(收费)。 - GCViewer是一个小工具,它可以可视化展示Sun / Oracle、IBM、HP和BEA的Java虚拟机生成的详细GC(垃圾收集)输出。这个工具可以支持多种格式的GC日志输入,包括G1、Parallel、CMS和Serial等,并且只需将日志文件拖放到主窗口,GCViewer就能自动识别并对其进行详细分析。此外,GCViewer还提供了详细的图表来展示GC活动,如不同代别的内存分配、GC事件的时间线、暂停时间分布等,使得用户能够迅速了解GC行为的特点和潜在问题。
没有gceasy好用,但是可以本地运行。
3.2 堆文件分析工具
-
jdk自带的工具jhat
进入到dump.hrof同目录下,执行命令$ jhat heap.hprof
Reading from heap.hprof...
Dump file created Wed Mar 22 15:20:48 CST 2023
Snapshot read, resolving...
Resolving 1250401 objects...
Chasing references, expect 250 dots..........................................................................................................................................................................................................................................................
Eliminating duplicate references..........................................................................................................................................................................................................................................................
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.
运行成功后使用浏览器访问
不太好用,没有分析
- Memory Analyzer Mat下载地址:Eclipse Memory Analyzer Open Source Project | The Eclipse Foundation
注意需要jdk17以上才能使用,jdk下载
可以直接指定运行的JRE
修改MemoryAnalyzer.ini文件,添加
-vm
C:\Program Files\Java\jdk-22\bin\javaw.exe
如图所示
导入堆文件后的显示