JDK中自帶的JVM分析工具

目錄

  • 一、業務背景
  • 二、Jdk-Bin目錄
  • 三、命令行工具
    • 1、jps命令
    • 2、jinfo命令
    • 3、jstat命令
    • 4、jstack命令
    • 5、jmap命令
  • 四、可視化工具
    • 1、jconsole
    • 2、visualvm
  • 五、參考源碼
內存溢出,妥妥的名場面;
一、業務背景對于分布式架構中的文件服務來說 , 由于涉及大量的IO流操作,很容易引發JVM的相關異常,尤其是內存溢出的問題;
JDK中自帶的JVM分析工具

文章插圖
在最近的一次版本迭代中,真實的業務處理場景和上述幾乎一致,由于在文件服務中添加批量處理的動作 , 直接喚醒了隱藏許久的BUG,就是最常見的內存溢出;
問題的起因:在word文檔完成內容識別后,轉換為pdf文件,然后進行頁面分割轉為一組圖片,在這個復雜并且超長的流程中存在一個數組容器未銷毀;
解決的方式:分析JVM的dump文件,定位OOM問題引發的根本原因,結合文件服務的異常日志分析,添加資源的釋放動作,從而解決問題;
二、Jdk-Bin目錄對于相當一部分新手來說,看到JVM的問題都是Bug不知所起一臉懵的,其實這種心態大可不必,從職場幾年的開發經驗上看,JVM的問題大致分為兩種:
  • 開發輕松解決:可以升級內存資源或者調整分配,又或者對程序優化,完成相關資源的管理和釋放,這是最常用的手段;
  • 輕松解決開發:由于經驗不足,程序出現重大BUG導致JVM異常 , 進而引起系列的連鎖反應 , 這種不會絕地反彈,只有一地雞毛;
在解決常規的JVM異常時 , 通常依賴JDK中基礎工具即可完成問題的定位,從而進行分析和解決,不過這些需要對基礎工具熟練使用才行,而很多JDK自身的能力又是經常被忽略的;
在jdk的bin目錄中,有很多自帶工具可以用于對JVM的分析;
JDK中自帶的JVM分析工具

文章插圖
上述是基于jdk1.8的目錄,里面有很多開發經常用到命令 , 下面圍繞一個微服務的啟動和運行 , 來看看基于JDK中自帶JVM工具的用法;
三、命令行工具1、jps命令jps:虛擬機進程狀態工具,該命令在Java環境部署和服務啟動查看時經常用到,首先在本地啟動一個facade門面微服務 , 然后在命令行中執行查詢;
  • jps:命令默認輸出的是進程ID和應用主類的名稱;
  • -l:輸出進程ID和應用主類的完整路徑;
  • -v:輸出向jvm傳遞的參數,此處展示為idea中顯式配置的VM-options參數,其他內容自行查看即可;
  • -m:輸出向main方法傳遞的參數,服務啟動前可以在idea的Program-arguments配置;
$ jps1281 FacadeApp$ jps -l1281 com.explore.facade.FacadeApp$ jps -v1281 FacadeApp -Xms128m -Xmx256m -XX:MaxNewSize=256m -XX:MaxPermSize=256m$ jps -m1281 FacadeApp hello,main-method2、jinfo命令jinfo:在命令后面帶pid進程號,可以輸出指定進程的配置信息,在應用啟動時通常不會指定過多的配置參數,就可以使用該命令查詢很多參數的默認值;該命令還可以在運行時動態調整部分參數,只是很少被使用;
$ jinfo 1281# 只粘貼個別參數Java System Properties: # 系統參數java.runtime.version=1.8.0_144-b01file.encoding=UTF-8sun.java.command=com.explore.facade.FacadeApp hello,main-methodVM Flags:# 虛擬機參數-XX:InitialHeapSize=134217728 -XX:MaxHeapSize=268435456 -XX:MaxNewSize=267911168VM Arguments:# 運行時參數jvm_args: -Xms128m -Xmx256m -XX:MaxNewSize=256m -XX:MaxPermSize=256mjava_command: com.explore.facade.FacadeApp hello,main-method$ jinfo -sysprops 1281# 只輸出【Java System Properties】參數$ jinfo -flags 1281# 只輸出【VM Flags】參數3、jstat命令jstat:以指定的頻率輸出JVM的監控指標,下述命令輸出內存占用和GC相關信息,每隔3秒輸出一次 , 連續打印5次;由于這里只是啟動一個簡單的微服務,沒有執行業務邏輯,所以各項指標比較平穩;
$ jstat -gcutil 1281 3000 5S0S1EOMCCSYGCYGCTFGCFGCTCGCCGCTGCT0.000.0057.9764.1692.8288.7530.02890.516--0.5440.000.0057.9764.1692.8288.7530.02890.516--0.544該命令是比較常用的,這里各項指標的統計邏輯,在tools.jar包中有jstat_options參考文檔,相對路徑sun/tools/jstat/resources/目錄下;
option gcutil {column {header "^S0^" /* Survivor 0 Space - Percent Used */data (1-((sun.gc.generation.0.space.1.capacity - sun.gc.generation.0.space.1.used)/sun.gc.generation.0.space.1.capacity)) * 100}column {header "^S1^" /* Survivor 1 Space - Percent Used */data (1-((sun.gc.generation.0.space.2.capacity - sun.gc.generation.0.space.2.used)/sun.gc.generation.0.space.2.capacity)) * 100}......}

推薦閱讀