Java虚拟机:性能监控与故障处理工具
概述:
給一個系統定位問題的時候,知識、經驗是關鍵基礎,數據是依據。工具是運用知識處理數據的手段。這里說的數據包括:運行日志、異常堆棧、GC日志、線程快照文件(threaddump/javacore文件)、堆轉儲快照(heapdump/hprof文件)等。
## JDK的命令行工具:
JDK的命令行工具大多數是對jdk/lib/tools.jar類庫的一層薄包裝而已,它們的主要功能代碼是在tools類庫中實現的。Linux下的這些工具有的甚至是用shell腳本編寫的。
SUN JDK監控和故障處理工具:
| jps | jvm process status tool,顯示指定系統內所有的hotspot虛擬機進程 |
| jstat | jvm statistics monitoring tool,用于收集hotspot虛擬機各方面的運行數據 |
| jinfo | configuration info for java,顯示虛擬機配置信息 |
| jmap | memory map for java,生成虛擬機的內存轉儲快照(heapdump文件) |
| jhat | jvm heap dump browser,用于分析heapmap文件,它會建立一個http/html服務器讓用戶可以在瀏覽器上查看分析結果 |
| jstack | stack trace for java ,顯示虛擬機的線程快照 |
一、 jps:虛擬機進程狀況工具:
可以列出正在運行的虛擬機進程,并顯示虛擬機執行主類名稱以及這些進程的本地虛擬機唯一ID。
jps命令格式?jps [options] [hostid]
jps可以通過RMI協議開啟了RMI服務的遠程虛擬機進程狀態,hostid為RMI注冊表中注冊的主機名。
jps常用的選項:
| -p | 只輸出LVMID,省略主類的名稱 |
| -m | 輸出虛擬機進程啟動時傳遞給主類main()函數的參數 |
| -l | 輸出主類的全名,如果進程執行的是jar包,輸出jar路徑 |
| -v | 輸出虛擬機進程啟動時jvm參數 |
二、jstat:虛擬機統計信息監視工具:
jstat是用于監視虛擬機各種運行狀態信息的命令行工具。它可以顯示本地或者遠程虛擬機進程中的類裝載、內存、垃圾回收、JIT編譯等運行數據。在沒有GUI圖形界面,只是提供了純文本控制臺環境的服務器上,它將是運行期定位虛擬機性能問題的首選工具。
jstat的命令格式:jstat [option vmid [interval [s|ms] [count]] ]
對于命令格式中的VMID和LVMID,如過是本地虛擬機進程,VMID和LVMID是一致的,如果是遠程虛擬機,那VMID的格式應當是:[protocol:] [//] lvmid[@hostname[:port]/servername].
參數interval 和count分別表示查詢的間隔和次數,如果省略這兩個參數,說明只查詢一次。
| -class | 監視裝載類、卸載類、總空間以及類裝載所耗費的時間 |
| -gc | 監視java堆狀況,包括eden區、兩個survivor區、老年代、永久代等的容量、已用空間、GC時間合計信息 |
| -gccapacity | 監視內容與-gc基本相同,但輸出主要關注java堆各個區域使用到最大、最小空間 |
| -gcutil | 監視內容與-gc基本相同,但輸出主要關注已使用控件占總空間的百分比 |
| -gccause | 與-gcutil功能一樣,但是會額外輸出導致上一次gc產生的原因 |
| -gcnew | 監視新生代GC情況 |
| -gcnewcapacity | 監視內容與-gcnew基本相同,輸出主要關注使用到的最大、最小空間 |
| -gcold | 監視老年代GC情況 |
| -gcoldcapacity | 監視內容與-gcold基本相同,輸出主要關注使用到的最大、最小空間 |
| -gcpermcapacity | 輸出永久代使用到的最大、最小空間 |
| -compiler | 輸出JIT編譯過的方法、耗時等信息 |
| -printcompilation | 輸出已經被JIT編譯過的方法 |
三、jinfo:Java配置信息工具:
jinfo命令的作用是實時地查看和調整虛擬機各項參數。
jinfo 命令格式:jinfo [option]? pid
四、jmap:java內存映像工具:
jmap命令用于生成堆轉儲快照(dump文件)。jmap的作用并不僅僅為了獲取dump文件,它還可以查詢finalize執行隊列、java堆和永久代的詳細信息。如空間使用率、當前用的是哪種收集器等。
jmap格式 jmap [option] vmid
| -dump | 生成java堆轉儲快照。格式為: -dump:[live,]format=b,file=,其中live子參數說明是否只dump出存活的對象 |
| -finalizerinfo | 顯示在F-Queue中等待Finalizer線程執行finalize方法的對象。只在Linux/Solaris平臺下有效 |
| -heap | 顯示java堆詳細信息,如使用哪種收集器、參數配置、分代情況等,在Linux/Solaris平臺下有效 |
| -jisto | 顯示堆中對象統計信息,包含類、實例對象、合集容量 |
| -permstat | 以ClassLoader為統計口徑顯示永久代內存狀態。只在Linux/Solaris平臺下有效 |
| -F | 當虛擬機進程對-dump選項沒有相應時。可使用這個選項強制生成dump快照。只在Linux/Solaris平臺下有效 |
五、jhat:虛擬機堆轉儲快照分析工具:
與jmap搭配使用,來分析dump生成的堆快照。jhat內置了一個微型的HTTP/HTML服務器,生成dump文件的分析結果后,可以在瀏覽器中查看。
用法舉例: jhat test1.bin
test1.bin為生成的dump文件。屏幕顯示“Server is ready.”的提示后,用戶在瀏覽器中鍵入http://localhost:7000就可以看到分析的結果了。分析結果默認是以包圍單位進行分組顯示,分析內存泄漏問題主要會使用到其中的“Heap Histogram”與OQL標簽的功能。前者可以找到內存中總容量最大的對象。后者是標準的對象查詢語言,使用類似SQL的語法對內存中的對象進行查詢統計。
六、jstack:java堆棧跟蹤工具:
jstack命令用于生成虛擬機當前時刻的線程快照(一般稱為threaddump或者javacore文件)。線程快照就是當前虛擬機內每一條線程正在執行的方法堆棧集合,生成線程快照的主要目的是定位線程出現長時間停頓的原因,如線程死鎖、死循環、請求外部資源導致長時間等待等。
jstack 格式?jstack [option] vmid
option選項的合法值和具體含義:
| -Fssssll | 當正常輸出dssssss的請求不被響應時,強制輸出線程堆棧 |
| -l | 除堆棧外,顯示關于鎖的附加信息 |
| -m | 如果調用到本地方法的話,可以顯示c/c++的堆棧 |
java.lang.Thread類中新增了一個getAllStackTraces()方法用于獲取虛擬機中所有線程的StackTraceElement對象。使用這個方法可以通過簡單的幾行代碼就完成jstack的大部分功能。
七、HSDIS:JIT生成代碼反匯編:
在Java虛擬機規范中,詳細描述了虛擬機指令集中每條指令的執行過程、執行前后對操作數棧、局部變量表的影響等細節。這些細節描述與Sun的早期虛擬機(Sun Classic VM)高度吻合,但隨著技術的發展,高性能虛擬機真正的細節實現方式已經漸漸與虛擬機規范所描述的內容產生了越來越大的差距,虛擬機規范中的描述逐漸成了虛擬機實現的“概念模型”——即實現只能保證規范描述等效。基于這個原因,我們分析程序的執行語義問題(虛擬機做了什么)時,在字節碼層面上分析完全可行,但分析程序的執行行為問題(虛擬機是怎樣做的、性能如何)時,在字節碼層面上分析就沒有什么意義了,需要通過其他方式解決。
分析程序如何執行,通過軟件調試工具(GDB、Windbg等)來斷點調試是最常見的手段,但是這樣的調試方式在Java虛擬機中會遇到很大困難,因為大量執行代碼是通過JIT編譯器動態生成到CodeBuffer中的,沒有很簡單的手段來處理這種混合模式的調試(不過相信虛擬機開發團隊內部肯定是有內部工具的)。因此,不得不通過一些特別的手段來解決問題,基于這種背景,本節的主角——HSDIS插件就正式登場了。
HSDIS是一個Sun官方推薦的HotSpot虛擬機JIT編譯代碼的反匯編插件,它包含在HotSpot虛擬機的源碼之中,但沒有提供編譯后的程序。在Project Kenai的網站也可以下載到單獨的源碼。它的作用是讓HotSpot的-XX:+PrintAssembly指令調用它來把動態生成的本地代碼還原為匯編代碼輸出,同時還生成了大量非常有價值的注釋,這樣我們就可以通過輸出的代碼來分析問題。讀者可以根據自己的操作系統和CPU類型從Project Kenai的網站上下載編譯好的插件,直接放到JDK_HOME/jre/bin/client和JDK_HOME/jre/bin/server目錄中即可。如果沒有找到所需操作系統(譬如Windows的就沒有)的成品,那就得自己使用源碼編譯一下。
還需要注意的是,如果讀者使用的是Debug或者FastDebug版的HotSpot,那可以直接通過-XX:+PrintAssembly指令使用插件;如果使用的是Product版的HotSpot,那還要額外加入一個-XX:+UnlockDiagnosticVMOptions參數。
八、JDK的可視化工具:
JDK中除了提供大量的命令行工具外,還有兩個功能強大的可視化工具:JConsole和VisualVM。
1、JConsole:
JConsole是一種基于JMX的可視化監視、管理工具。他管理部分的功能是針對JMX MBean進行管理。
JConsole工具在JDK/bin目錄下,啟動JConsole后,將自動搜索本機運行的jvm進程,不需要jps命令來查詢指定。雙擊其中一個jvm進程即可開始監控,也可使用“遠程進程”來連接遠程服務器。
2、Visual VM:多合一故障處理工具:
VisualVM是一個集成多個JDK命令行工具的可視化工具。VisualVM基于NetBeans平臺開發,它具備了插件擴展功能的特性,通過插件的擴展,可用于顯示虛擬機進程及進程的配置和環境信息(jps,jinfo),監視應用程序的CPU、GC、堆、方法區及線程的信息(jstat、jstack),dump以及分析堆轉儲快照(jmap、jhat)等。VisualVM在JDK/bin目錄下。
VisualVM的性能分析功能甚至比起JProfiler、YourKit等專業且收費的Profiling工具都不會遜色多少,而且VisualVM還有一個很大的優點:不需要被監視的程序基于特殊Agent運行,因此它對應用程序的實際性能的影響很小,使得它可以直接應用在生產環境中。這個優點是JProfiler、YourKit等工具無法與之媲美的。
總結
以上是生活随笔為你收集整理的Java虚拟机:性能监控与故障处理工具的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java设计模式之行为型:解释器模式
- 下一篇: MySQL数据库:explain执行计划