[转帖]java获取到heapdump文件后,如何快速分析?

java,获取,heapdump,文件,如何,快速,分析 · 浏览次数 : 0

小编点评

**问题分析:** * 出现内存问题,触发堆内存占用高报警,但没有触发OOM。 * 问题所在接口是用于查询商品数据的接口,当输入3时会查询出所有3开头的商品,而这有20w+数据。 * 通过访问日志,定位到问题接口是用来查询商品数据的接口。 * MAT 分析发现线程栈上的Request参数对象包含接口URL信息。 **问题解决:** 1. 确定问题接口的地址。 2. 分析请求参数对象,找到接口URL。 3. 使用VisualVM 查看线程栈,找到请求线程的日志。 4. 分析日志中获取的接口URL,并使用该 URL 在接口中查找相关代码。 **注意事项:** * MAT 的分析路径可能比较复杂,需要耐心观察线程栈和参数。 * 问题的解决需要结合理论知识和技术技能。

正文

https://www.jianshu.com/p/aaf56385766d

 

 

简介

在之前的OOM问题复盘之后,本周,又一Java服务出现了内存问题,这次问题不严重,只会触发堆内存占用高报警,没有触发OOM,但好在之前的复盘中总结了dump脚本,会在堆占用高时自动执行jstack与jmap,使得我们成功保留了问题现场。

查看堆占用分布

发现有heapdump文件后,我立马拷贝到本机,并使用MAT分析,如下:

 
mat

很显然,好像是什么接口分配了非常大的String对象,一个String对象约200MB,那它是哪分配的呢?

 

查找大对象分配线程

这个分配行为肯定是某个线程做的,而线程是最常见的GC Root,因此只要查找对象的GC Root即可,如下:

 
gc_root

找到了大对象对应的分配线程是http-nio-8088-exec-6,如下:
 
image.png

 

查看线程栈

如何查看这个线程在干什么呢?在MAT中摸索了一会,没找到相关内容,回想起我们的dump脚本中记录了jstack,打开看看,如下:

 
image.png

可以发现,这个线程正在做json序列化,但我仔细找了好一会,也没有找到相关接口的Controller,这是因为线程已经执行完了Controller里面的逻辑,之后返回接口响应数据时分配的大对象。

 

可是,线程栈中没有业务代码,就没法定位是哪个接口有问题了。。。

检查accesslog日志

考虑到分配大对象的接口肯定会很慢,于是我转向查看tomcat的accesslog日志,如下:

 
image.png

终于,找到了问题接口,这个接口是用来查询商品数据的,当输入3时会查询出所有3开头的商品,而这有20w+数据,解决问题很简单,加个limit完事。

 

排查过程复盘

然而,我一直有个习惯,就是解决一个问题后,我会反思一下问题解决过程中有多少运气成分。

如果你经常阅读排查问题类的技术文章,就会发现不少文章,中间突然有一步定位到了问题根因,可能是突然发现了一个线索,或是硬看代码看出来的,或是猜测某处有问题,我觉得这种排查过程都有不少运气成分,我希望问题是通过多年理论基础的积累和对诊断工具的熟练使用,而有章法的一步步查出来的。

而上面通过accesslog能够定位到问题,有一定的运气成分,因为本次内存问题不极端,如果此接口请求量大,那就会瞬间触发多次FGC,进而会影响其它接口也变慢,进而无法分辨出哪个是导致问题的接口!

我想,从理论上来说,Java堆文件里面,应该有线程栈以及线程栈上的参数,因为线程是对象,参数也是对象,它们理应都在堆里,于是我找了个空闲时间,又摸索起MAT这个工具了。

MAT查看线程栈

摸索了一会,我就发现有这样一个按钮,可以查看线程信息,如下:

 
image.png

 

找到前面说的线程http-nio-8088-exec-6,展开后,就可以发现线程栈以及栈上的参数,如下:

 
image.png

 

这就找到了请求的Request参数对象,再将Request对象多次展开后,就可以找到接口url信息,如下:

 
image.png

嗯,这样分析heapdump文件真tm的高效啊😁

 

MAT下载地址:https://www.eclipse.org/mat/downloads.php

VisualVM查看线程栈

考虑到不少同学习惯用VisualVM分析heapdump,这里也放一下VisualVM的使用方法。

首先,加载heapdump文件,如下:

 
image.png

 

然后选择相应对象,右键选择Select in Threads,如下:

 
image.png

 

定位到线程栈后,找到要查看的Request对象,点击进入,如下:


 
image.png

同样,展开Request对象后,可找到url信息,如下:

 
image.png

 

VisualVM下载地址:https://visualvm.github.io/download.html

总结

虽然我也用MAT很多次了,但每次问题都太简单,以至于没有深入使用过MAT,导致到现在才知道有如此便捷的分析路径。

与[转帖]java获取到heapdump文件后,如何快速分析?相似的内容:

[转帖]java获取到heapdump文件后,如何快速分析?

https://www.jianshu.com/p/aaf56385766d 简介 在之前的OOM问题复盘之后,本周,又一Java服务出现了内存问题,这次问题不严重,只会触发堆内存占用高报警,没有触发OOM,但好在之前的复盘中总结了dump脚本,会在堆占用高时自动执行jstack与jmap,使得我们

[转帖]Java 获取 Kafka 指定 topic 的消息总量

发表于 2020-11-29 分类于 Java , Apache , JavaClass , Kafka Valine: 0 Kafka Consumer API Kafka 提供了两套 API 给 Consumer The high-level Consumer API The SimpleCon

[转帖]查看docker中运行的JVM参数问题及解决方法

方法一、jcmd命令: 1、jps获取java的线程id 2、jcmd pidVM.flags获取 51152:-XX:CICompilerCount=3 -XX:InitialHeapSize=526385152 -XX:MaxHeapSize=1073741824 -XX:MaxNewSize=

[转帖]jcmd命令详解

1 基本知识 jcmd 是在 JDK1.7 以后,新增了一个命令行工具。 jcmd 是一个多功能的工具,相比 jstat 功能更为全面的工具,可用于获取目标 Java 进程的性能统计、JFR、内存使用、垃圾收集、线程堆栈、JVM 运行时间,也可以手动执行 GC、导出(TODO 能导出线程信息?)线程

[转帖]JVM-工具-jcmd

http://events.jianshu.io/p/011f0e3a39ff 一、jcmd 用法 1.1 基本知识 jcmd 是在 JDK1.7 以后,新增了一个命令行工具。 jcmd 是一个多功能的工具,相比 jstat 功能更为全面的工具,可用于获取目标 Java 进程的性能统计、JFR、内存

[转帖]jcmd命令详解

1 基本知识 jcmd 是在 JDK1.7 以后,新增了一个命令行工具。 jcmd 是一个多功能的工具,相比 jstat 功能更为全面的工具,可用于获取目标 Java 进程的性能统计、JFR、内存使用、垃圾收集、线程堆栈、JVM 运行时间,也可以手动执行 GC、导出(TODO 能导出线程信息?)线程

[转帖]jconsole远程监控认证,java远程监控,jmx监控应用,jmx ssl配置,jconsole ssl连接远程应用

知识普及 jmx JMX(java Management Extensions)是一个Java平台的管理和监控接口。任何程序,只要按JMX规范访问这个接口,就可以获取所有管理与监控信息,jconsole与Java VisualVM等常见监测工具都是基于jmx,JMX不但可以用于管理JVM,还可以管理

[转帖] shell管道咋堵住了

https://www.cnblogs.com/codelogs/p/16060378.html 背景# 起因是这样的,我们想开发一个小脚本,当cpu使用率过高时,使用jstack将java的线程栈保存下来,以便后面分析。 获取cpu使用率# 获取cpu使用率是比较容易的,使用vmstat就可以了,

[转帖]Java方法的JIT编译

https://www.jianshu.com/p/a6275e239eac Java方法执行一般会利用分层编译,先通过c1解释执行。方法执行编译等级逐渐提升,有机会通过JIT编译为特定平台汇编执行,以此获得最好的性能。 方法执行除了达到一定热度外,是否JIT编译也受到以下两个参数影响: -XX:+

[转帖]引人入胜,实战讲解“Java性能调优六大工具”之linux命令行工具

Java性能调优六大工具之Linux命令行工具 为了能准确获得程序的性能信息,需要使用各种辅助工具。本章将着重介绍用于系统性能分析的各种工具。熟练掌握这些工具,对性能瓶颈定位和系统故障排查都很有帮助。 1,Linux命令行工具2, Windows工具3,JDK命令行工具4,JConsole工具5,