JVM性能调优监控工具专题一:JVM自带性能调优工具

Posted Elvis_lfc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JVM性能调优监控工具专题一:JVM自带性能调优工具相关的知识,希望对你有一定的参考价值。

前提概要: 

       JDK本身提供了很多方便的JVM性能调优监控工具,除了集成式的VisualVM和jConsole外,还有jps、jstack、jmap、jhat、jstat、hprof等小巧的工具,每一种工具都有其自身的特点,用户可以根据你需要检测的应用或者程序片段的状况,适当的选择相应的工具进行检测。接下来的两个专题分别会讲VisualVM的具体应用。


现实企业级Java开发中,有时候我们会碰到下面这些问题:

  • OutOfMemoryError,内存不足

  • 内存泄露

  • 线程死锁

  • 锁争用(Lock Contention)

  • Java进程消耗CPU过高

  • ......

这些问题在日常开发中可能被很多人忽视(比如有的人遇到上面的问题只是重启服务器或者调大内存,而不会深究问题根源),但能够理解并解决这些问题是Java程序员进阶的必备要求。


基本工具命令

 

    jps

      实际中这是最常用的命令,下面要介绍的小工具更多的都是先要使用jps查看出当前有哪些Java进程,获取该Java进程的id后再对该进程进行处理。

    jps主要用来输出JVM中运行的进程状态信息。语法格式如下:

    

[plain]  view plain  copy
  1. jps [options] [hostid]    

 如果不指定hostid就默认为当前主机或服务器。

   命令行参数选项说明如下:

[plain]  view plain  copy
  1. -q 不输出类名、Jar名和传入main方法的参数  
  2. -m 输出传入main方法的参数  
  3. -l 输出main类或Jar的全限名  
  4. -v 输出传入JVM的参数  

  比如

1、我现在有一个WordCountTopo的Strom程序正在本机运行。

2、使用java -jar deadlock.jar & 启动一个线程死锁的程序 

[plain]  view plain  copy
  1. wangsheng@WANGSHENG-PC /E  
  2. $ jps -ml  
  3. 14200 deadlock.jar  
  4. 13952 com.wsheng.storm.topology.WordCountTopo D://input/ 3  
  5. 13248 sun.tools.jps.Jps -ml  
  6. 9728  

    jstack 

jstack主要用来查看某个Java进程内的线程堆栈信息。语法格式如下:

[plain]  view plain  copy
  1. jstack [option] pid  
  2. jstack [option] executable core  
  3. jstack [option] [server-id@]remote-hostname-or-ip  

命令行参数选项说明如下 [plain]  view plain  copy
  1. -l long listings,会打印出额外的锁信息,在发生死锁时可以用  jstack -l pid  来观察锁持有情况  
  2. -m mixed mode,不仅会输出Java堆栈信息,还会输出C/C++堆栈信息(比如Native方法)  

  jstack可以定位到线程堆栈,根据堆栈信息我们可以定位到具体代码,所以它在JVM性能调优中使用得非常多。

    下面我们来一个实例:

     找出某个Java进程中最耗费CPU的Java线程并定位堆栈信息,用到的命令有ps、top、printf、jstack、grep。

   

    先找出Java进程ID,服务器上的Java应用名称为wordcount.jar:

[plain]  view plain  copy
  1. [root@storm-master home]# ps -ef | grep wordcount | grep -v grep  
  2. root       2860   2547 13 02:09 pts/0    00:02:03 java -jar wordcount.jar /home/input 3  

    得到进程ID为2860(也可以使用其它方式得到java的进程号),

 

    找出该进程内最耗费CPU的线程,可以使用如下3个命令,这里我们使用第3个命令得出如下结果:

[plain]  view plain  copy
  1. 1)ps -Lfp pid : 即 ps -Lfp 2860  
  2. 2)ps -mp pid -o THREAD, tid, time :即 ps -mp 2860 -o THREAD,tid,time  
  3. 3)top -Hp pid: 即   top -Hp 2860  


 

  TIME列就是各个Java线程耗费的CPU时间,显然CPU时间最长的是ID为2968的线程,用 

[plain]  view plain  copy
  1. printf "%x\\n" 2968  

    得到2968的十六进制值为b98,下面会用到。     

    终于轮到jstack上场了,它用来输出进程2860的堆栈信息,然后根据线程ID的十六进制值grep,如下: 

[plain]  view plain  copy
  1. [root@storm-master home]# jstack 2860 | grep b98  
  2. "SessionTracker" prio=10 tid=0x00007f55a44e4800 nid=0xb53 in Object.wait() [0x00007f558e06c000  

 可以看到CPU消耗在SessionTracker这个类的Object.wait(),于是就能很容易的定位到相关的代码了。

 

jmap和 jhat


     jmap用来查看堆内存使用状况,一般结合jhat使用。

 

     jmap语法格式如下: 

[plain]  view plain  copy
  1. jmap [option] pid  
  2. jmap [option] executable core  
  3. jmap [option] [server-id@]remote-hostname-or-ip  

 如果运行在64位JVM上,由于linux操作系统的不同,可能需要指定-J-d64命令选项参数。

 

    打印进程的类加载器和类加载器加载的持久代对象信息: jmap -permstat pid

个人感觉这个不是太有用

 

输出:类加载器名称、对象是否存活(不可靠)、对象地址、父类加载器、已加载的类大小等信息,如图:

 


    查看进程堆内存使用情况:包括使用的GC算法、堆配置参数和各代中堆内存使用jmap -heap pid

比如下面的例子 

[plain]  view plain  copy
  1. [root@storm-master home]# jmap -heap 2860  
  2. Attaching to process ID 2860, please wait...  
  3. Debugger attached successfully.  
  4. Server compiler detected.  
  5. JVM version is 20.45-b01  
  6.   
  7. using thread-local object allocation.  
  8. Mark Sweep Compact GC  
  9.   
  10. Heap Configuration:  
  11.    MinHeapFreeRatio = 40  
  12.    MaxHeapFreeRatio = 70  
  13.    MaxHeapSize      = 257949696 (246.0MB)  
  14.    NewSize          = 1310720 (1.25MB)  
  15.    MaxNewSize       = 17592186044415 MB  
  16.    OldSize          = 5439488 (5.1875MB)  
  17.    NewRatio         = 2  
  18.    SurvivorRatio    = 8  
  19.    PermSize         = 21757952 (20.75MB)  
  20.    MaxPermSize      = 85983232 (82.0MB)  
  21.   
  22. Heap Usage:  
  23. New Generation (Eden + 1 Survivor Space):  
  24.    capacity = 12189696 (11.625MB)  
  25.    used     = 6769392 (6.4557952880859375MB)  
  26.    free     = 5420304 (5.1692047119140625MB)  
  27.    55.53372290826613% used  
  28. Eden Space:  
  29.    capacity = 10878976 (10.375MB)  
  30.    used     = 6585608 (6.280525207519531MB)  
  31.    free     = 4293368 (4.094474792480469MB)  
  32.    60.53518272307982% used  
  33. From Space:  
  34.    capacity = 1310720 (1.25MB)  
  35.    used     = 183784 (0.17527008056640625MB)  
  36.    free     = 1126936 (1.0747299194335938MB)  
  37.    14.0216064453125% used  
  38. To Space:  
  39.    capacity = 1310720 (1.25MB)  
  40.    used     = 0 (0.0MB)  
  41.    free     = 1310720 (1.25MB)  
  42.    0.0% used  
  43. tenured generation:  
  44.    capacity = 26619904 (25.38671875MB)  
  45.    used     = 15785896 (15.054603576660156MB)  
  46.    free     = 10834008 (10.332115173339844MB)  
  47.    59.30110040967841% used  
  48. Perm Generation:  
  49.    capacity = 33554432 (32.0MB)  
  50.    used     = 33323352 (31.779624938964844MB)  
  51.    free     = 231080 (0.22037506103515625MB)  
  52.    99.31132793426514% used  

    查看堆内存中的对象数目、大小统计直方图,如果带上live则只统计活对象:jmap -histo[:live] pid

 

[plain]  view plain  copy
  1. [root@storm-master Desktop]# jmap -histo 2860  
  2.   
  3.  num     #instances         #bytes  class name  
  4. ----------------------------------------------  
  5.    1:         13917       11432488  [B  
  6.    2:          6117        6181448  <instanceKlassKlass>  
  7.    3:         39520        6004504  <constMethodKlass>  
  8.    4:          6117        5517072  <constantPoolKlass>  
  9.    5:         39520        5383280  <methodKlass>  
  10.    6:          5148        3150944  <constantPoolCacheKlass>  
  11.    7:         29954        2810640  [C  
  12.    8:         50179        2469272  <symbolKlass>  
  13.    9:         42122        1791704  [Ljava.lang.Object;  
  14.   10:          1804         961464  <methodDataKlass>  
  15.   11:         11747         941200  [Ljava.util.HashMap$Entry;  
  16.   12:         28786         921152  java.lang.String  
  17. jvm 性能调优工具之 jstat 命令详解

    Java故障分析基础

    JVM性能调优监控工具jpsjstackjmapjhatjstat使用详解

    JVM性能调优监控工具

    JVM调优日志解析分析与性能监控工具

    JVM性能调优监控工具jpsjstackjmapjhatjstathprof使用详解