JVM調優工具的使用(jps,jstat,jstack,jmap,jhat)
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
[root@zabbix-agent bin]# jps -l 1217 sun.tools.jps.Jps 1094 org.apache.catalina.startup.Bootstrap 也可以通過 ps -ef|grep java 查看所有Java應用進程
二 jstat命令
jstat 它可以顯示出虛擬機進程中的類裝載、內存、垃圾收集、JIT編譯等運行數據
1 類加載統計:
[root@zabbix-agent bin]# jstat -class 1094 Loaded Bytes Unloaded Bytes Time 3133 6273.2 0 0.0 1.91 ====================== Loaded:加載class的數量 Bytes:所占用空間大小 Unloaded:未加載數量 Bytes:未加載占用空間 Time:時間 ======================
2 編譯統計
[root@zabbix-agent 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 垃圾回收統計
[root@zabbix-agent 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次 [root@zabbix-agent 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 [root@zabbix-agent 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 [root@zabbix-agent bin]# jps -l 1217 sun.tools.jps.Jps 1094 org.apache.catalina.startup.Bootstrap [root@zabbix-agent 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消耗情況
[root@zabbix-agent 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時間是最大的,用命令查看線程的十六進制值
[root@zabbix-agent bin]# printf "%x\n" 1103 44f 查詢到的值44f 用於下面jstack 定位信息
[root@zabbix-agent 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查看
[root@zabbix-agent /]# jmap -dump:format=b,file=/tmp/dump.dat 1094 Dumping heap to /tmp/dump.dat ... Heap dump file created [root@zabbix-agent /]# 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.
下面就可以瀏覽器界面查看了
JVM調優工具的使用(jps,jstat,jstack,jmap,jhat)