排查流程
1.定位进程找出哪个进程的问题
2.找出进程对应线程id
3.线程id--->16进制 : 问题线程的id 转换为16进制线程id
4.找出线程的详细信息: jstack +进程id | grep -i +线程的16进制id,与开发沟通
5.jmap -heap +进程id 显示jvm的内存使用情况
6.jmap (导出 jvm内存的内容 )
jmap -dump:format=b,file=/tmp/java-dmp.bin 1425
format=b: 指定了转储文件的格式为二进制(binary)
file=/tmp/java-dmp.bin: 指定了输出文件的路径和名称
1425: 这是你要生成堆转储的 Java 进程的进程 ID(PID)
7.给开发分析jvm导出文件
排查案例
#01.找出问题java进程
[root@web03 ~]# top
查找出占用高的进程 ,为1425
#02通过进程 找出问题线程
[root@web03 ~]# top -Hp 1425
查找出占用高的线程,为1459
-H 代表显示线程
-p 后面跟着的是进程ID
#03. 线程id转换为16进制
[root@web03 ~]# echo 'obase=16;1459' |bc
5B3
#04. 通过jstack pid 过滤 java线程id(16进制)信息
[root@web03 ~]# jstack 1425 |grep -i '5B3'
"main" #1 prio=5 os_prio=0 tid=0x00007f733c009800 nid=0x5b3 runnable [0x00007f734223c000]
[root@web03 ~]# jstack 1425 |grep -A5 -i '5B3'
"main" #1 prio=5 os_prio=0 tid=0x00007f733c009800 nid=0x5b3 runnable [0x00007f734223c000]
java.lang.Thread.State: RUNNABLE
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:409)
at java.net.ServerSocket.implAccept(ServerSocket.java:545)
at java.net.ServerSocket.accept(ServerSocket.java:513)
#05. 把jvm内存使用情况 导出
[root@web03 ~]# jmap -heap 1425 #java进程pid
Attaching to process ID 1425, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.60-b23
using thread-local object allocation.
Mark Sweep Compact GC
Heap Configuration:
MinHeapFreeRatio = 40
..........
#06. 把jvm内存信息导出文件
jmap -dump:format=b,file=/root/tomcat.bin pid(java进程)
[root@web03 ~]# jmap -dump:format=b,file=/tmp/java-dmp.bin 1425
Dumping heap to /tmp/java-dmp.bin ...
Heap dump file created
[root@web03 ~]# ll -h /tmp/java-dmp.bin
-rw------- 1 root root 26M Aug 15 14:46 /tmp/java-dmp.bin
[root@web03 ~]# file /tmp/java-dmp.bin
/tmp/java-dmp.bin: data
#07. 下载到windows 通过mat软件分析
mat eclipse Memory Analyzer (MAT)
MemoryAnalyzer.exe
两个tomcat同时挂掉,排查到/var/log/messages日志Dec 3 15:56:42 rybh-web-02 kernel: Killed process 5211 (java), UID 0, total-vm:6689280kB, anon-rss:4263820kB, file-rss:0kB, shmem-rss:0kB,说明程序使用内存太多,导致直接被kill掉。