1. 程式人生 > >【轉載】JVM調優工具的使用(jps,jstat,jstack,jmap,jhat)

【轉載】JVM調優工具的使用(jps,jstat,jstack,jmap,jhat)

文章目錄

原文連結:http://blog.51cto.com/superleedo/2132016

JDK本身提供了很豐富的效能監控工具,除了整合式的visualVM和jConsole外,還有jstat,jstack,jps,jmap,jhat小工具,這些都是效能調優的常用工具

我們在Java的開發中,常常會遇到下面這些問題:

1記憶體不足,2記憶體洩漏,3鎖爭用,4執行緒鎖死,5java程序消耗CPU過高等

這些問題出現的時候 大家常常通過重啟伺服器或者調大記憶體來臨時解決

一,jps命令

jps主要用來輸出JVM中執行的程序狀態資訊

命令列引數選項:

-q 不輸出類名、Jar名和傳入main方法的引數

-m 輸出傳入main方法的引數

-l 輸出main類或Jar的全限名

-v 輸出傳入JVM的引數

最常用的是 jps -l

[[email protected] bin]# jps -l
1217 sun.tools.jps.Jps
1094 org.apache.catalina.startup.Bootstrap

也可以通過 ps -ef|grep java 檢視所有Java應用程序

二 jstat命令

jstat 它可以顯示出虛擬機器程序中的類裝載、記憶體、垃圾收集、JIT編譯等執行資料

1 類載入統計:

[[email protected] bin]# jstat -class 1094
Loaded  Bytes  Unloaded  Bytes     Time   
  3133  6273.2        0     0.0       1.91

======================
Loaded:載入class的數量
Bytes:所佔用空間大小
Unloaded:未載入數量
Bytes:未載入佔用空間
Time:時間
======================

2 編譯統計

[[email protected] bin]# jstat -compiler 1094
Compiled Failed Invalid   Time   FailedType FailedMethod
    1994      1       0     5.23          1 org/apache/tomcat/util/IntrospectionUtils setProperty
    
===================
Compiled:編譯數量。
Failed:失敗數量
Invalid:不可用數量
Time:時間
FailedType:失敗型別
FailedMethod:失敗的方法
===================

3 垃圾回收統計

[[email protected] bin]# jstat -gc 1094
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
832.0  832.0   96.4   0.0    7040.0   6278.2   17372.0    16028.9   20224.0 19493.8 2304.0 2056.7     18    0.141   1      0.030    0.171

====================
S0C : survivor0區的總容量
S1C : survivor1區的總容量
S0U : survivor0區已使用的容量
S1C : survivor1區已使用的容量
EC : Eden區的總容量
EU : Eden區已使用的容量
OC : Old區的總容量
OU : Old區已使用的容量
PC 當前perm的容量 (KB)
PU perm的使用 (KB)
YGC : 新生代垃圾回收次數
YGCT : 新生代垃圾回收時間
FGC : 老年代垃圾回收次數
FGCT : 老年代垃圾回收時間
GCT : 垃圾回收總消耗時間
====================

jstat -gc 1094 3000 10

這個命令意思就是每隔3000ms輸出1094的gc情況,一共輸出10次

[[email protected] bin]# jstat -gcutil 1094    已使用空間佔總空間的百分比
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   
  0.00  12.48   6.74  92.27  96.39  89.27     19    0.158     1    0.030    0.187
  
[[email protected] bin]# jstat -gccapacity 1094    同-gc,不過還會輸出Java堆各區域使用到的最大、最小空間 (堆記憶體統計)
 NGCMN    NGCMX     NGC     S0C   S1C       EC      OGCMN      OGCMX       OGC         OC       MCMN     MCMX      MC     CCSMN    CCSMX     CCSC    YGC    FGC 
  5440.0  83264.0   8704.0  832.0  832.0   7040.0    10944.0   166592.0    17372.0    17372.0      0.0 1067008.0  20224.0      0.0 1048576.0   2304.0     19     1

更多jstat命令引數 可參看https://www.cnblogs.com/lizhonghua34/p/7307139.html

三 jstack命令

jstack主要用來檢視某個Java程序內的執行緒堆疊資訊,jstack可以定位到執行緒堆疊,根據堆疊資訊我們可以定位到具體程式碼,所以它在JVM效能調優中使用得非常多。

命令列引數選項

-l long listings,會打印出額外的鎖資訊,在發生死鎖時可以用jstack -l pid來觀察鎖持有情況

-m mixed mode,不僅會輸出Java堆疊資訊,還會輸出C/C++堆疊資訊(比如Native方法)

常用命令 jstack PID (切換到對應使用者下)

下面通過一個示例說明;

例項找出某個Java程序中最耗費CPU的Java執行緒並定位堆疊資訊,用到的命令有ps、top、printf、jstack、grep。

首先找出應用程序的PID

ps -ef|grep java

[[email protected] bin]# jps -l
1217 sun.tools.jps.Jps
1094 org.apache.catalina.startup.Bootstrap

[[email protected] bin]# ps -ef|grep java
root       1094      1  0 18:35 pts/0    00:00:17 /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.161-0.b14.el7_4.x86_64/bin/java -Djava.util.logging.config.file=/home/apache-tomcat-8.5.31/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /home/apache-tomcat-8.5.31/bin/bootstrap.jar:/home/apache-tomcat-8.5.31/bin/tomcat-juli.jar -Dcatalina.base=/home/apache-tomcat-8.5.31 -Dcatalina.home=/home/apache-tomcat-8.5.31 -Djava.io.tmpdir=/home/apache-tomcat-8.5.31/temp org.apache.catalina.startup.Bootstrap start

找到應用程序的PID為1094,接著找出該程序最消耗CPU的執行緒,可以使用ps -Lfp 1094 或者top -Hp 1094來檢視該程序中執行緒的cpu消耗情況

[[email protected] bin]# top -Hp 1094
top - 19:40:51 up  1:52,  1 user,  load average: 0.00, 0.01, 0.05
Threads:  44 total,   0 running,  44 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.3 sy,  0.0 ni, 99.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :   998628 total,    84224 free,   690548 used,   223856 buff/cache
KiB Swap:  2097148 total,  2068536 free,    28612 used.   146256 avail Mem 

   PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                         
  1094 root      20   0 2778656  84996   5324 S  0.0  8.5   0:00.00 java                                            
  1095 root      20   0 2778656  84996   5324 S  0.0  8.5   0:01.01 java                                            
  1096 root      20   0 2778656  84996   5324 S  0.0  8.5   0:00.54 java                                            
  1097 root      20   0 2778656  84996   5324 S  0.0  8.5   0:00.00 java                                            
  1098 root      20   0 2778656  84996   5324 S  0.0  8.5   0:00.00 java                                            
  1099 root      20   0 2778656  84996   5324 S  0.0  8.5   0:00.00 java                                            
  1100 root      20   0 2778656  84996   5324 S  0.0  8.5   0:03.06 java                                            
  1101 root      20   0 2778656  84996   5324 S  0.0  8.5   0:01.46 java                                            
  1102 root      20   0 2778656  84996   5324 S  0.0  8.5   0:00.00 java                                            
  1103 root      20   0 2778656  84996   5324 S  0.0  8.5   0:06.76 java                                            
  1104 root      20   0 2778656  84996   5324 S  0.0  8.5   0:00.59 java

檢視到執行緒1103的消耗CPU時間是最大的,用命令檢視執行緒的十六進位制值

[[email protected] bin]# printf "%x\n" 1103
44f

查詢到的值44f 用於下面jstack 定位資訊

[[email protected] bin]# jstack 1094|grep 44f
"VM Periodic Task Thread" os_prio=0 tid=0x00007f602c01bc80 nid=0x44f waiting on condition

這樣就可以看到VM Periodic Task Thread 是最耗時的類,然後就可以去程式碼審查程式碼了。

四 jmap

jmap命令引數

dump : 生成堆轉儲快照
finalizerinfo : 顯示在F-Queue佇列等待Finalizer執行緒執行finalizer方法的物件
heap : 顯示Java堆詳細資訊
histo : 顯示堆中物件的統計資訊
permstat : to print permanent generation statistics
F : 當-dump沒有響應時,強制生成dump快照
常用情況,用jmap把程序記憶體使用情況dump到檔案中,再用jhat分析檢視

jmap -dump:format=b,file=/tmp/dump.dat 1094
生成dump.dat檔案
dump出來的檔案可以用MAT、VisualVM等工具檢視,這裡用jhat檢視

[[email protected] /]# jmap -dump:format=b,file=/tmp/dump.dat 1094
Dumping heap to /tmp/dump.dat ...
Heap dump file created
[[email protected] /]# jhat -port 9999 /tmp/dump.dat 
Reading from /tmp/dump.dat...
Dump file created Sat Jun 23 20:34:39 CST 2018
Snapshot read, resolving...
Resolving 274150 objects...
Chasing references, expect 54 dots......................................................
Eliminating duplicate references......................................................
Snapshot resolved.
Started HTTP server on port 9999
Server is ready.

下面就可以瀏覽器介面查看了

在這裡插入圖片描述