排查java异常进程的方法

定位JAVA进程中异常线程的方法

日常使用中我们往往会遇到JAVA进程内存飙高,程序hang住,cpu的load过高等情况。这时候往往需要定位到JAVA的实例看下具体占用CPU、内存过高的线程都在做什么?
下面总结了下如何定位JAVA问题线程的方法。

找到有问题的JVM进程

linux命令:top–找到有问题的JAVA进程
shift+p 按照cpu排序
shift+m按照内存排序

查看有问题JAVA进程中的线程

linux命令:top -H -p pid 查看pid进程下所有有问题的线程

  1. 将十进制数换成16进制:printf “%x\n” tid
  2. 查看进程下的线程正在执行的方法: jstack pid |grep nid=0x【tid】 -A 30

jstack查看出来的线程信息梳理

线程的几种状态

  1. RUNNABLE,线程处于执行中
  2. BLOCKED,线程被阻塞
  3. WAITING,线程正在等待

对于锁的竞争,可参照下面的思路排查问题:

1
2
3
4
线程1获取到锁,处于RUNNABLE状态,线程2处于BLOCK状态;  
1、locked <0x000000076bf62208>说明线程1对地址为0x000000076bf62208对象进行了加锁;
2、waiting to lock <0x000000076bf62208> 说明线程2在等待地址为0x000000076bf62208对象上的锁;
3、waiting for monitor entry [0x000000001e21f000]说明线程1是通过synchronized关键字进入了监视器的临界区,并处于"Entry Set"队列,等待monitor;

jmap查看JVM系统信息的命令

查找JVM中系统的大小和个数

1
2
3
4
5
按照个数统计  
jmap -histo:live pid|grep keyword|sort -k 2 -g -r|head -10

按照占用大小统计
jmap -histo:live pid|grep keyword|sort -k 2 -g -r|head -10

查看JVM中Heap的情况

1
jmap -heap pid

情况如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
Attaching to process ID Pid, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.65-b01

using parallel threads in the new generation.
using thread-local object allocation.
Concurrent Mark-Sweep GC

Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 4294967296 (4096.0MB)
NewSize = 858980352 (819.1875MB)
MaxNewSize = 858980352 (819.1875MB)
OldSize = 3435986944 (3276.8125MB)
NewRatio = 4
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 0 (0.0MB)

Heap Usage:
New Generation (Eden + 1 Survivor Space):
capacity = 773128192 (737.3125MB)
used = 9882512 (9.424697875976562MB)
free = 763245680 (727.8878021240234MB)
1.2782501145683225% used
Eden Space: (Edn区)
capacity = 687276032 (655.4375MB)
used = 9882512 (9.424697875976562MB)
free = 677393520 (646.0128021240234MB)
1.4379247260000476% used
From Space: (Survivor中的From)
capacity = 85852160 (81.875MB)
used = 0 (0.0MB)
free = 85852160 (81.875MB)
0.0% used
To Space: (Survivor中的To)
capacity = 85852160 (81.875MB)
used = 0 (0.0MB)
free = 85852160 (81.875MB)
0.0% used
concurrent mark-sweep generation: (老年代)
capacity = 3435986944 (3276.8125MB)
used = 258117296 (246.1598358154297MB)
free = 3177869648 (3030.6526641845703MB)
7.512173364067357% used