【JVM】GC导致的性能问题排查与解决方案,日志、堆分析工具介绍

一、必要性

重要应用程序在使用过程中,忽然无法响应用户请求,排查发现网络联通无问题,gateway能够正常接收分发请求,应用进程正常,正常向注册中心发送请求,但是接收http请求全部返回报错。

添加gc后发现内存回收耗时太长,无法恢复。

二、定位问题

  1. 确定网络请求无问题。
  2. 进程正常。
  3. 打印gc报错信息,确定是否为gc回收问题。

2.1 gc回收问题定位

  1. 先查询本应用的内存使用情况:

jps -l 查询正在运行的所有应用

确认出问题应用的内存使用情况

top -p <PID> 在top界面中,你可以看到包括RES(常驻集大小,即进程当前使用的、未交换出的物理内存大小)和%MEM(进程使用的物理内存百分比)在内的内存相关统计信息。

jmap -heap pid 查看堆使用情况

jstat -gc pid 1000相隔一秒输出一次内存使用情况

  1. 查看较长时间的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 日志文件的输出路径
  1. 堆使用情况
  • 已经出现问题后: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日志分析工具

  1. 在线分析工具https://gceasy.io/

    GCEasy是一款在线的GC(垃圾收集)日志分析器,它可以用于分析JVM(Java虚拟机)的垃圾回收日志,提供可视化的分析结果和建议。GCEasy具有内置的智能功能,能够自动检测JVM和Android GC日志中的问题,并为之推荐解决方案(收费)。
  2. GCViewer是一个小工具,它可以可视化展示Sun / Oracle、IBM、HP和BEA的Java虚拟机生成的详细GC(垃圾收集)输出。这个工具可以支持多种格式的GC日志输入,包括G1、Parallel、CMS和Serial等,并且只需将日志文件拖放到主窗口,GCViewer就能自动识别并对其进行详细分析。此外,GCViewer还提供了详细的图表来展示GC活动,如不同代别的内存分配、GC事件的时间线、暂停时间分布等,使得用户能够迅速了解GC行为的特点和潜在问题。

    没有gceasy好用,但是可以本地运行。

3.2 堆文件分析工具

  1. 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.

运行成功后使用浏览器访问

不太好用,没有分析

  1. 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

如图所示

导入堆文件后的显示

相关推荐
陈大爷(有低保)5 分钟前
UDP Socket聊天室(Java)
java·网络协议·udp
kinlon.liu19 分钟前
零信任安全架构--持续验证
java·安全·安全架构·mfa·持续验证
王哲晓40 分钟前
Linux通过yum安装Docker
java·linux·docker
java66666888844 分钟前
如何在Java中实现高效的对象映射:Dozer与MapStruct的比较与优化
java·开发语言
Violet永存1 小时前
源码分析:LinkedList
java·开发语言
执键行天涯1 小时前
【经验帖】JAVA中同方法,两次调用Mybatis,一次更新,一次查询,同一事务,第一次修改对第二次的可见性如何
java·数据库·mybatis
gopher95111 小时前
linux驱动开发-中断子系统
linux·运维·驱动开发
Jarlen1 小时前
将本地离线Jar包上传到Maven远程私库上,供项目编译使用
java·maven·jar
蓑 羽1 小时前
力扣438 找到字符串中所有字母异位词 Java版本
java·算法·leetcode
码哝小鱼1 小时前
firewalld封禁IP或IP段
linux·网络