1、定位系統問題 依據 GC日誌 堆轉儲快照(heapdump/hprof文件) 線程快照(threaddump/javacore文件) 運行日誌 異常堆棧 分析依據的工具 jps:顯示指定系統內的所有JVM進程 jstat:收集JVM各方面的運行數據 jinfo:顯示JVM配置信息 jmap:形成
1、定位系統問題
- 依據
- GC日誌
- 堆轉儲快照(heapdump/hprof文件)
- 線程快照(threaddump/javacore文件)
- 運行日誌
- 異常堆棧
- 分析依據的工具
- jps:顯示指定系統內的所有JVM進程
- jstat:收集JVM各方面的運行數據
- jinfo:顯示JVM配置信息
- jmap:形成堆轉儲快照(heapdump文件)
- jhat:分析heapdump文件
- jstack:顯示JVM的線程快照
- jconsole
- visualVM
說明:後邊兩種是具有圖形化界面的。
2、jps(是其他所有命令的基礎)
作用:列出所有的JVM虛擬機進程。
格式:jps -l
3、jstat(是沒有GUI界面的情況下,在運行期定位JVM性能問題的首選)
作用:查看gc數據和類載入卸載數據
格式:jstat option PID interval count
意義:每隔interval毫秒做一次option,一共做count次
說明:S0(from區)使用了41.74%;S1(to區)使用了0;E(Eden區)使用了54.35%;O(Old,年老代)使用了62.41%;P(Perment,永久代)使用了99.63%;YGC(Young GC)了32次,YGCT(Young GC Time)花銷0.132秒;FGC(Full GC)了1次,FGCT(Full GC Time)花銷0.102秒;GCT(GC Time)總花銷0.234秒。
分析:其實上邊這個查詢結果可以直接看出,我們需要加大P(永久代大小)
說明:載入了3683個類,總共占有4355.3位元組;卸載了0個類,卸載的類的位元組數為0,類的載入與卸載共花銷3.16秒
更多的jstat的使用,參看http://my.oschina.net/skyline520/blog/304805
4、jinfo
作用:查看和運行期修改JVM的配置參數
格式:jinfo -flag parameter PID
說明:查看3732進程下的MaxTenuringThreshold參數值。
說明:修改3732進程下的MaxTenuringThreshold參數值,但是windows下失敗。
5、jmap
作用:生成堆轉儲快照和查看最占記憶體的元素,用於分析記憶體泄露問題
格式(生成堆轉儲快照):jmap -dump:format=b,file=文件名 PID
說明:生成了3732進程的堆轉儲文件myfile
格式(查看最占記憶體的元素):jmap -histo PID
說明:結果自己去看,太多了
6、jhat
作用:分析堆轉儲快照(與jmap配合)
格式:jhat 文件名
說明:執行上述命令後,打開localhost:7000,找到如下紅框部分打開,這裡才是我們最關註的東西。
註意:該工具是萬不得已才用的。
推出命令使用"ctrl+c"
7、jstack
作用:生成線程快照,定位線程長時間卡頓的原因(線程間死鎖、死迴圈、請求外部資源導致的長時間等待)
格式:jstack -l PID
說明:查看3732進程中的所有線程的堆棧信息
《深入理解Java虛擬機》的作者提供了一個工具jsp頁面,使得我們可以在程式運行時,隨時運行該jsp頁面,來查看線程堆棧信息,代碼如下:
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8" import="java.util.Map"%> 3 <!DOCTYPE html> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <title>jstack</title> 8 </head> 9 <body> 10 <% 11 for(Map.Entry<Thread, StackTraceElement[]> stackTrace : Thread.getAllStackTraces().entrySet()){ 12 Thread thread = (Thread)stackTrace.getKey(); 13 StackTraceElement[] elements = (StackTraceElement[])stackTrace.getValue(); 14 15 /* if(thread.equals(Thread.currentThread())){ 16 continue; 17 } */ 18 out.println("\n線程:"+thread.getName()+"\n"); 19 for(StackTraceElement ele : elements){ 20 out.println("\t"+ele+"\n"); 21 } 22 } 23 %> 24 </body> 25 </html>View Code
註意:代碼中我註釋掉一段,是因為想也查出當前線程的堆棧信息,作者並沒有這個註釋。
總結:
- JVM性能相關的6個常用的JDK命令
- jps:查詢JVM中的所有進程,找出將要操作的PID,是所有命令的基礎
- jstat:查看相應JVM進程的gc、類載入卸載信息,是沒有GUI界面查看JVM運行數據的首選
- jinfo:查看和在運行期動態修改JVM配置參數
- jmap:生成堆轉儲快照和比較占記憶體的對象
- jhat:配合jmap分析堆轉儲日誌,除非沒有其他工具可做這個事兒,否則就不用該工具
- jstack:生成線程快照,定位線程長時間卡頓的原因(線程間死鎖、死迴圈、請求外部資源導致的長時間等待)
- 輸出gc信息到控制台
- -XX:+PrintGCDetails:輸出GC的詳細信息
- -XX:+PrintGCTimeStamps:輸出GC的時間信息
- -XX:+PrintGCApplicatonStoppedTime:GC造成的應用暫停的時間
- -XX:+PrintGCDetails:輸出GC的詳細信息
- 輸出gc信息到文件
- 以上三個參數在這裡依舊適用
- -Xloggc:文件路徑/gc.log:輸出到文件