java自帶內存分析工具詳解

本文已收錄至公衆號:灰太狼學爪哇。(一個java程序員都在關注的公衆號)

前言

在進行java程序問題定位時,內存問題定位是很關鍵的一招。雖然現在成熟的JVM調優工具有很多,比如jconsole、大名鼎鼎的VisualVM,以及最常用的IBM的Memory Analyzer等等,但是在碰到線上問題的時候,這些工具卻使用起來不是很方便,這個時候java自帶的命令工具,就非常有用了。

Sun JDK監控和故障處理命令有jps jstat jmap jhat jstack jinfo下面做一一介紹。

jps

JVM Process Status Tool,顯示指定系統內所有的HotSpot虛擬機進程。

命令格式
jps [option] [hostid]
option參數
-l : 輸出主類全名或jar路徑
-q : 只輸出LVMID
-m : 輸出JVM啓動時傳遞給main()的參數
-v : 輸出JVM啓動時顯示指定的JVM參數

其中 [option]和[hostid]可以不寫。

示例
$ jps -l
57296
65941 org.jetbrains.kotlin.daemon.KotlinCompileDaemon
66296 org.apache.catalina.startup.Bootstrap
66312 sun.tools.jps.Jps
66219 org.jetbrains.jps.cmdline.Launcher
66301 org.jetbrains.jps.cmdline.Launcher

jstat

jstat(JVM statistics Monitoring)是用於監視虛擬機運行時狀態信息的命令,它可以顯示出虛擬機進程中的類裝載、內存、垃圾收集、JIT編譯(Just In Time Compiler, 即時編譯器)等運行數據。

命令格式
jstat [option] LVMID [interval] [count]
參數
[option] : 操作參數
LVMID : 本地虛擬機進程ID
[interval] : 連續輸出的時間間隔
[count] : 連續輸出的次數	
option參數總覽
-class 	class loader的行爲統計
-compiler 	HotSpt JIT編譯器行爲統計
-gc		垃圾回收堆的行爲統計
-gccapacity 	各個垃圾回收代容量(young,old,perm)和他們相應的空間統計
-gcutil		垃圾回收統計概述
-gccause		垃圾收集統計概述(同-gcutil),附加最近兩次垃圾回收事件的原因
-gcnew		新生代行爲統計
-gcnewcapacity		新生代與其相應的內存空間的統計
-gcold		年老代和永生代行爲統計
-gcoldcapacity		年老代行爲統計
-gcpermcapacity		 永生代行爲統計
-printcompilation		HotSpot編譯方法統計

jmap

jmap(JVM Memory Map)命令用於生成heap dump文件,如果不使用這個命令,還闊以使用-XX:+HeapDumpOnOutOfMemoryError參數來讓虛擬機出現OOM的時候·自動生成dump文件。 jmap不僅能生成dump文件,還闊以查詢finalize執行隊列、Java堆和永久代的詳細信息,如當前使用率、當前使用的是哪種收集器等。

命令格式
jmap [option] pid
option參數
dump : 生成堆轉儲快照
finalizerinfo : 顯示在F-Queue隊列等待Finalizer線程執行finalizer方法的對象
heap : 顯示Java堆詳細信息
histo : 顯示堆中對象的統計信息
permstat : to print permanent generation statistics
F :-dump沒有響應時,強制生成dump快照
示例
jmap -dump:live,format=b,file=<filename> pid 

這樣就可以導出pid對應java進程的dump文件了。

jhat

jhat(JVM Heap Analysis Tool)命令是與jmap搭配使用,用來分析jmap生成的dump,jhat內置了一個微型的HTTP/HTML服務器,生成dump的分析結果後,可以在瀏覽器中查看。在此要注意,一般不會直接在服務器上進行分析,因爲jhat是一個耗時並且耗費硬件資源的過程,一般把服務器生成的dump文件複製到本地或其他機器上進行分析。

命令格式
jhat [dumpfile]
參數
-stack false|true 關閉對象分配調用棧跟蹤(tracking object allocation call stack)。 如果分配位置信息在堆轉儲中不可用. 則必須將此標誌設置爲 false. 默認值爲 true.>
-refs false|true 關閉對象引用跟蹤(tracking of references to objects)。 默認值爲 true. 默認情況下, 返回的指針是指向其他特定對象的對象,如反向鏈接或輸入引用(referrers or incoming references), 會統計/計算堆中的所有對象。>
-port port-number 設置 jhat HTTP server 的端口號. 默認值 7000.>
-exclude exclude-file 指定對象查詢時需要排除的數據成員列表文件(a file that lists data members that should be excluded from the reachable objects query)。 例如, 如果文件列列出了 java.lang.String.value , 那麼當從某個特定對象 Object o 計算可達的對象列表時, 引用路徑涉及 java.lang.String.value 的都會被排除。>
-baseline exclude-file 指定一個基準堆轉儲(baseline heap dump)。 在兩個 heap dumps 中有相同 object ID 的對象會被標記爲不是新的(marked as not being new). 其他對象被標記爲新的(new). 在比較兩個不同的堆轉儲時很有用.>
-debug int 設置 debug 級別. 0 表示不輸出調試信息。 值越大則表示輸出更詳細的 debug 信息.>
-version 啓動後只顯示版本信息就退出>
-J< flag > 因爲 jhat 命令實際上會啓動一個JVM來執行, 通過 -J 可以在啓動JVM時傳入一些啓動參數. 例如, -J-Xmx512m 則指定運行 jhat 的Java虛擬機使用的最大堆內存爲 512 MB. 如果需要使用多個JVM啓動參數,則傳入多個 -Jxxxxxx.
示例
$ jhat -J-Xmx512m dump.hprof
  eading from dump.hprof...
  Dump file created Fri Mar 11 17:13:42 CST 2016
  Snapshot read, resolving...
  Resolving 271678 objects...
  Chasing references, expect 54 dots......................................................
  Eliminating duplicate references......................................................
  Snapshot resolved.
  Started HTTP server on port 7000
  Server is ready.

中間的-J-Xmx512m是在dump快照很大的情況下分配512M內存去啓動HTTP服務器,運行完之後就可在瀏覽器打開Http://localhost:7000進行快照分析 堆快照分析主要在最後面的Heap Histogram裏,裏面根據class列出了dump的時候所有存活對象。

分析同樣一個dump快照,MAT需要的額外內存比jhat要小的多的多,所以建議使用MAT來進行分析。

jstack

jstack用於生成java虛擬機當前時刻的線程快照。線程快照是當前java虛擬機內每一條線程正在執行的方法堆棧的集合,生成線程快照的主要目的是定位線程出現長時間停頓的原因,如線程間死鎖、死循環、請求外部資源導致的長時間等待等。 線程出現停頓的時候通過jstack來查看各個線程的調用堆棧,就可以知道沒有響應的線程到底在後臺做什麼事情,或者等待什麼資源。

命令格式
jstack [option] pid
參數
-F : 當正常輸出請求不被響應時,強制輸出線程堆棧
-l : 除堆棧外,顯示關於鎖的附加信息
-m : 如果調用到本地方法的話,可以顯示C/C++的堆棧

執行完命令後,會打印出一堆堆棧信息,這裏有一篇文章分析的比較好:jstack線程棧分析

jinfo

jinfo(JVM Configuration info)這個命令作用是實時查看和調整虛擬機運行參數。 之前的jps -v口令只能查看到顯示指定的參數,如果想要查看未被顯示指定的參數的值就要使用jinfo口令

命令格式
jinfo [option] [args] pid
參數
-flag : 輸出指定args參數的值
-flags : 不需要args參數,輸出所有JVM參數的值
-sysprops : 輸出系統屬性,等同於System.getProperties()

總結

本篇文章較爲系統的總結了JVM自帶的分析工具,但是要把這些工具命令全部使用或者是熟悉還是有難度的,只是選擇一種比較熟悉的作爲主要工具,其他工具可以作爲定位問題的參考,另外說一句,其實jconsole還是比較好用,可以實時顯示同時可以對內存進行dump操作。

本篇文章主要參考:http://www.ityouknow.com/jvm/2017/09/03/jvm-command.html

我是灰太狼,一個95後自我精進的java程序員。個人運營的公衆號:灰太狼學爪哇。你想知道的都在這裏。(關注免費領取100G各階段的學習、面試資料)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章