jvm调优之jstack

版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/qq2430/article/details/82319958

概述

jstack [ options ] pid

  • options:命令行选项
  • pid:进程ID

jstack命令可以用来查看线程堆栈。根据堆栈信息我们可以定位程序出现的问题,例如CPU偏高等问题。本文使用的是JDK10,不同版本间可能存在差异。

options

不添加options的时候,默认查看线程堆栈信息

[root@izbp1chtb8a3vd2mzvuawlz target]# jstack 13969|more
2018-09-02 22:01:27
Full thread dump Java HotSpot(TM) 64-Bit Server VM (10.0.2+13 mixed mode):

Threads class SMR info:
_java_thread_list=0x00007fc06c0014f0, length=31, elements={
0x00007fc0a00af800, 0x00007fc0a00b2000, 0x00007fc0a00c6800, 0x00007fc0a00c8000,
0x00007fc0a00ca000, 0x00007fc0a00cb800, 0x00007fc0a0148000, 0x00007fc0a0152800,
0x00007fc0a0b1e800, 0x00007fc0a071a000, 0x00007fc0a0552000, 0x00007fc0a08a3800,
0x00007fc0a07f7800, 0x00007fc0a07a5000, 0x00007fc0a05fd800, 0x00007fc0a09dd800,
0x00007fc0a06c6800, 0x00007fc0a0a41800, 0x00007fc0a0a3e000, 0x00007fc0a0795800,
0x00007fc0a04b7800, 0x00007fc0a05eb000, 0x00007fc0a0246000, 0x00007fc0a0769000,
0x00007fc0a000f000, 0x00007fc05c3df800, 0x00007fc05c3ef800, 0x00007fc05c3f0800,
0x00007fc05c142000, 0x00007fc05c143800, 0x00007fc06c002800
}

"Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007fc0a00af800 nid=0x3694 waiting on condition  [0x00007fc085265000]
   java.lang.Thread.State: RUNNABLE
        at java.lang.ref.Reference.waitForReferencePendingList(java.base@10.0.2/Native Method)
        at java.lang.ref.Reference.processPendingReferences(java.base@10.0.2/Reference.java:174)
        at java.lang.ref.Reference.access$000(java.base@10.0.2/Reference.java:44)
        at java.lang.ref.Reference$ReferenceHandler.run(java.base@10.0.2/Reference.java:138)

"Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007fc0a00b2000 nid=0x3695 in Object.wait()  [0x00007fc085164000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(java.base@10.0.2/Native Method)
        - waiting on <0x00000000f5bc0938> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(java.base@10.0.2/ReferenceQueue.java:151)
        - waiting to re-lock in wait() <0x00000000f5bc0938> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(java.base@10.0.2/ReferenceQueue.java:172)
        at java.lang.ref.Finalizer$FinalizerThread.run(java.base@10.0.2/Finalizer.java:216)

"Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007fc0a00c6800 nid=0x3696 runnable  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007fc0a00c8000 nid=0x3697 waiting on condition  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE
   No compile task

-l:输出有关锁的其他信息。

[root@izbp1chtb8a3vd2mzvuawlz target]# jstack -l 13969|more
2018-09-02 21:58:28
Full thread dump Java HotSpot(TM) 64-Bit Server VM (10.0.2+13 mixed mode):

Threads class SMR info:
_java_thread_list=0x00007fc06c0014f0, length=31, elements={
0x00007fc0a00af800, 0x00007fc0a00b2000, 0x00007fc0a00c6800, 0x00007fc0a00c8000,
0x00007fc0a00ca000, 0x00007fc0a00cb800, 0x00007fc0a0148000, 0x00007fc0a0152800,
0x00007fc0a0b1e800, 0x00007fc0a071a000, 0x00007fc0a0552000, 0x00007fc0a08a3800,
0x00007fc0a07f7800, 0x00007fc0a07a5000, 0x00007fc0a05fd800, 0x00007fc0a09dd800,
0x00007fc0a06c6800, 0x00007fc0a0a41800, 0x00007fc0a0a3e000, 0x00007fc0a0795800,
0x00007fc0a04b7800, 0x00007fc0a05eb000, 0x00007fc0a0246000, 0x00007fc0a0769000,
0x00007fc0a000f000, 0x00007fc05c3df800, 0x00007fc05c3ef800, 0x00007fc05c3f0800,
0x00007fc05c142000, 0x00007fc05c143800, 0x00007fc06c002800
}

"Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007fc0a00af800 nid=0x3694 waiting on condition  [0x00007fc085265000]
   java.lang.Thread.State: RUNNABLE
        at java.lang.ref.Reference.waitForReferencePendingList(java.base@10.0.2/Native Method)
        at java.lang.ref.Reference.processPendingReferences(java.base@10.0.2/Reference.java:174)
        at java.lang.ref.Reference.access$000(java.base@10.0.2/Reference.java:44)
        at java.lang.ref.Reference$ReferenceHandler.run(java.base@10.0.2/Reference.java:138)

   Locked ownable synchronizers:
        - None

"Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007fc0a00b2000 nid=0x3695 in Object.wait()  [0x00007fc085164000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(java.base@10.0.2/Native Method)
        - waiting on <0x00000000f5bc0938> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(java.base@10.0.2/ReferenceQueue.java:151)
        - waiting to re-lock in wait() <0x00000000f5bc0938> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(java.base@10.0.2/ReferenceQueue.java:172)
        at java.lang.ref.Finalizer$FinalizerThread.run(java.base@10.0.2/Finalizer.java:216)

   Locked ownable synchronizers:
        - None

-h | -help:输出帮助信息。

[root@izbp1chtb8a3vd2mzvuawlz target]# jstack -h
Usage:
    jstack [-l] <pid>
        (to connect to running process)

Options:
    -l  long listing. Prints additional information about locks
    -h or -help to print this help message

使用示例

1 首先我们使用top命令,查看cpu偏高的进程,可以看到13969的进程cpu利用率已经到达99.3%

[root@izbp1chtb8a3vd2mzvuawlz target]# top
top - 22:03:23 up 6 days,  1:10,  1 user,  load average: 1.02, 1.31, 1.40
Tasks:  68 total,   1 running,  67 sleeping,   0 stopped,   0 zombie
%Cpu(s):100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  1015440 total,   315900 free,   407956 used,   291584 buff/cache
KiB Swap:        0 total,        0 free,        0 used.   450064 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                                                                                                        
13969 root      20   0 2518236 141388  17068 S 99.3 13.9  42:38.25 java                                                                                                                                           
  936 root      20   0  292652  13668   1512 S  0.3  1.3   6:20.00 docker-containe                                                                                                                                
 1160 root      20   0   65372   2144   1728 S  0.3  0.2   3:16.37 aliyun-service                                                                                                                                 
14336 root      20   0  161956   2208   1552 R  0.3  0.2   0:00.02 top                                                                                                                                            
    1 root      20   0   43536   3084   1872 S  0.0  0.3   0:05.53 systemd                                                                                                                                        
    2 root      20   0       0      0      0 S  0.0  0.0   0:00.00 kthreadd                                                                                                                                       
    3 root      20   0       0      0      0 S  0.0  0.0   0:01.90 ksoftirqd/0     

2 然后使用jstack命令将线程堆栈输出到文件中

[root@izbp1chtb8a3vd2mzvuawlz /]# jstack 13969 > 13969.stack
[root@izbp1chtb8a3vd2mzvuawlz /]# ls   
13969.stack  bin  boot  config  dev  etc  heap.bin  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

3 使用top -Hp查看哪个线程的cpu利用率偏高

[root@izbp1chtb8a3vd2mzvuawlz /]# top -Hp 13969
top - 22:07:13 up 6 days,  1:14,  1 user,  load average: 1.79, 1.39, 1.40
Threads:  34 total,   1 running,  33 sleeping,   0 stopped,   0 zombie
%Cpu(s):100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  1015440 total,   315916 free,   407856 used,   291668 buff/cache
KiB Swap:        0 total,        0 free,        0 used.   450164 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                                                                                                        
14021 root      20   0 2518236 141388  17068 R 99.7 13.9  46:15.79 pool-1-thread-1                                                                                                                                
13980 root      20   0 2518236 141388  17068 S  0.3 13.9   0:01.35 VM Periodic Tas                                                                                                                                
13969 root      20   0 2518236 141388  17068 S  0.0 13.9   0:00.00 java                                                                                                                                           
13970 root      20   0 2518236 141388  17068 S  0.0 13.9   0:02.77 java                                                                                                                                           
13971 root      20   0 2518236 141388  17068 S  0.0 13.9   0:00.61 VM Thread                                                                                                                                      
13972 root      20   0 2518236 141388  17068 S  0.0 13.9   0:00.00 Reference Handl                                                                                                                                
13973 root      20   0 2518236 141388  17068 S  0.0 13.9   0:00.00 Finalizer                                                                                                                                      
13974 root      20   0 2518236 141388  17068 S  0.0 13.9   0:00.00 Signal Dispatch                                                                                                                                
13975 root      20   0 2518236 141388  17068 S  0.0 13.9   0:02.96 C2 CompilerThre                                                                                                                                
13976 root      20   0 2518236 141388  17068 S  0.0 13.9   0:01.34 C1 CompilerThre   

4 如上文所式,14021这个线程的cpu利用率最高,我们将14021转换为16进制。

[root@izbp1chtb8a3vd2mzvuawlz /]# printf '%x\n' 14021
36c5

5 打开刚才保存的stack文件,搜索36c5,可以看到是StackAnalysisService的loop方法导致的,线程的状态RUNNABLE,其余线程都在都在等待这个线程释放锁。

...skipping...
"pool-1-thread-1" #33 prio=5 os_prio=0 tid=0x00007fc05c3df800 nid=0x36c5 runnable  [0x00007fc084133000]
   java.lang.Thread.State: RUNNABLE
        at com.zs.study.analysis.service.StackAnalysisService.loop(StackAnalysisService.java:17)
        at com.zs.study.analysis.service.StackAnalysisService.run(StackAnalysisService.java:9)
        - locked <0x00000000f0a82680> (a com.zs.study.analysis.service.StackAnalysisService)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@10.0.2/ThreadPoolExecutor.java:1135)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@10.0.2/ThreadPoolExecutor.java:635)
        at java.lang.Thread.run(java.base@10.0.2/Thread.java:844)

"pool-1-thread-2" #34 prio=5 os_prio=0 tid=0x00007fc05c3ef800 nid=0x36c6 waiting for monitor entry  [0x00007fc0637d8000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at com.zs.study.analysis.service.StackAnalysisService.run(StackAnalysisService.java:9)
        - waiting to lock <0x00000000f0a82680> (a com.zs.study.analysis.service.StackAnalysisService)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@10.0.2/ThreadPoolExecutor.java:1135)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@10.0.2/ThreadPoolExecutor.java:635)
        at java.lang.Thread.run(java.base@10.0.2/Thread.java:844)

猜你喜欢

转载自blog.csdn.net/qq2430/article/details/82319958