【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

如图所示

导入堆文件后的显示

相关推荐
Rain_Rong7 分钟前
linux检测硬盘
linux·运维·服务器
过过过呀Glik11 分钟前
在 Ubuntu 上安装 Muduo 网络库的详细指南
linux·c++·ubuntu·boost·muduo
小灰灰要减肥13 分钟前
装饰者模式
java
张铁铁是个小胖子24 分钟前
MyBatis学习
java·学习·mybatis
我曾经是个程序员33 分钟前
鸿蒙学习记录之http网络请求
服务器·学习·http
真真-真真1 小时前
WebXR
linux·运维·服务器
Yan.love1 小时前
开发场景中Java 集合的最佳选择
java·数据结构·链表
椰椰椰耶1 小时前
【文档搜索引擎】搜索模块的完整实现
java·搜索引擎
大G哥1 小时前
java提高正则处理效率
java·开发语言
轩辰~1 小时前
网络协议入门
linux·服务器·开发语言·网络·arm开发·c++·网络协议