排查流程
- 定位进程找出哪个进程的问题
- 找出进程对应线程id
- 线程id--->16进制 : 问题线程的id 转换为16进制线程id
- 找出线程的详细信息: jstack +进程id | grep -i +线程的16进制id,与开发沟通
- jmap -heap +进程id 显示jvm的内存使用情况
- jmap (导出 jvm内存的内容 )
- 给开发分析jvm导出文件
排查案例
# 1.找出问题java进程
top # 查找出占用高的进程 ,为24574
# 2.通过进程,找出问题线程
top -Hp 24574
# 查找出占用高的线程,为24671
# -H 代表显示线程
# -p 后面跟着的是进程ID
# 3.线程id转换为16进制
echo 'obase=16;24671' |bc
605F
# 4.通过jstack pid 过滤 java线程id(16进制)信息
jstack 24574 |grep -i '605F'
"http-nio-8080-exec-9" #27 daemon prio=5 os_prio=0 tid=0x00007fb87c87b800 nid=0x605f waiting on condition [0x00007fb86054e000]
jstack 24574 |grep -A5 -i '605F'
"http-nio-8080-exec-9" #27 daemon prio=5 os_prio=0 tid=0x00007fb87c87b800 nid=0x605f waiting on condition [0x00007fb86054e000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000867ca748> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
# 5.把jvm内存使用情况 导出
jmap -heap 24574 #进程id
Attaching to process ID 24574, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.401-b10
using thread-local object allocation.
Parallel GC with 4 thread(s)
Heap Configuration:
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 2051014656 (1956.0MB)
NewSize = 42991616 (41.0MB)
MaxNewSize = 683671552 (652.0MB)
OldSize = 87031808 (83.0MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 0 (0.0MB)
.........
# 6.把jvm内存信息导出文件
jmap -dump:format=b,file=/tmp/java-dmp.bin 24574
# format=b: 指定了转储文件的格式为二进制(binary)
# file=/tmp/java-dmp.bin: 指定了输出文件的路径和名称
# 24574: 这是你要生成堆转储的 Java 进程的进程 ID(PID)
file /tmp/java-dmp.bin
/tmp/java-dmp.bin: data
ll /tmp/java-dmp.bin
-rw-------. 1 root root 90954966 6月 13 12:36 /tmp/java-dmp.bin
# 7.给到开发进行分析