一、jstack排查问题
生产环境最近老是发生oom
top命令查看占用内存最高的java进程为927
top -H -p 927 查看927进程对应的线程
sudo jstack -F 927 > xxx.log 想要打印所有的线程栈信息,可是确报了如下异常
查看jdk版本
另一个环境1.8.0_91 jstack就可以猜测是jdk版本问题
二、jmap结合MemoryAnalyzer排查问题 PlanaA
现在只能用jmap来排查问题了jmap -dump:live,format=b,file=927.hprof 927
把java进程都dump成927.hprof文件
下载下来文件发现有927.hprof有4G多MemoryAnalyzer工具打开后根本无法解析,只能采用planB
三、jmap结合MemoryAnalyzer排查问题 PlanaB
下载LINUX的MAT地址:http://www.eclipse.org/mat/downloads.php
MemoryAnalyzer.ini 配置文件可以修改最大的内存,默认1G基本够用了。
在linux执行分析命令
./ParseHeapDump.sh 927.hprof org.eclipse.mat.api:suspects org.eclipse.mat.api:overview org.eclipse.mat.api:top_components。
解压927_Top_Components.zip进入index.html
可以看到RollbarService类里有两个对象占用了大量的空间
解压927_System_Overview.zip进入index.html
Class Histogram也可以找到蛛丝马迹大概是rollar包引起的(shallow heap和 retained heap的单位都是byte)
四、名词解释
所有包含Heap Profling功能的工具(MAT, Yourkit, JProfiler, TPTP等)都会使用到两个名词,一个是Shallow Size,另一个是 Retained Size.
Shallow Size
对象自身占用的内存大小,不包括它引用的对象。
Retained Size
Retained Size=当前对象大小+当前对象可直接或间接引用到的对象的大小总和
五、正常排查流程总结
内存溢出分析 JAVA dump查看线程运行情况: =====查看栈信息======================= 1.查询java程序pid netstat -ntpl | grep 8080 2.使用jstack [-l] 进程pid > xxx.log将进程里所有线程信息输入到指定文件中 1)如果程序正常运行:使用jstack [-l] 进程pid > xxx.log将所有线程信息输入到指定文件中 2)如果程序无响应:使用 jstack -F [-m] [-l] 进程pid >xxx.log强制打印栈信息 =====查看堆信息======================= 3.使用top命令找出占用cpu高(或者执行时间很长)的进程pid 4.使用top -H -p 线程pid 找出占用cpu高(或执行时间长)的线程pid 5.将占用cpu高的线程pid转换成16进制(window自带计算器) 6.dump该进程的内存 jmap -dump:format=b,file=文件名 [进程pid] 将转换后的pid在开始输出的dump文件(xxx.log)中搜索对应线程信息 7.eclipse Memory Analyzer 对dump文件分析
参考文章:https://www.cnblogs.com/But-you/p/10431543.html