1. 功能簡介
jmap
是 JDK
自帶的工具軟件,可用於生成指定 Java 進程的 Heap Dump 文件, 也可以查看堆內對象實例的統計信息、ClassLoader 的信息以及 finalizer 隊列中等待被回收的對象的信息。 JDK 自帶的工具都有 Java 進程所屬用戶的概念,需注意如果當前登錄用戶和進程啓動用戶不是同一個時,該命令無法獲取到正確信息
2. 使用方式
在終端界面使用 man jmap
可以方便地獲得 jmap
命令幫助文檔,其命令格式如下
命令格式 | 參數說明 |
---|---|
jmap [ option ] pid | pid 爲 Java 應用程序的進程號 |
jmap [ option ] executable core | executable 爲產生core dump的 java可執行程序,core爲打印出的core文件 |
jmap [ option ] [ server-id@] remote-hostname-or-IP | remote-hostname-or-ip 是遠程 debug 服務器的名稱或IP,server-id是唯一id,假如一臺主機上有多個遠程 debug 服務會需要區分 |
Options | 功能 |
---|---|
< no option > | 使用不帶選項參數的jmap 命令將會打印目標虛擬機中加載的每個共享對象的起始地址、映射大小以及共享對象文件的路徑全稱 |
-dump:[live,]format=b,file=< filename > | 以 hprof 二進制格式轉儲 Java 堆到指定 fileName 的文件中。如果指定了live 子選項,只有 Active 狀態的對象會被轉儲,會觸發 Full GC , gc log 中關鍵字爲 Heap Dump Initiated GC ,可以使用jhat (Java堆分析工具)讀取生成的 heap dump 文件 |
-finalizerinfo | 打印等待回收的對象信息 |
-heap | 打印堆的簡要信息,包括使用的GC算法、堆配置信息和generation wise heap usage |
-histo[:live] | 打印堆中對象信息,包括每個Java類、對象數量、內存大小(單位:字節)、完全限定的類名。打印的虛擬機內部的類名稱將會帶有一個’*’前綴。如果指定了live 子選項,則只計算活動的對象,會觸發 Full GC ,gc log 中的關鍵字爲 Heap Inspection Initiated GC |
-clstats | Java 8 之後 HotSpot 虛擬機永久代取消,取代 -permstat 的參數選項,可打印元空間的類加載器的統計信息。對於每個類加載器而言,它的名稱、活躍度、地址、父類加載器、它所加載的類的數量和大小都會被打印。另外,包含的字符串數量和大小也會被打印 |
-F | 強制模式,如果指定的 pid 沒有響應,建議使用 jmap -dump 或 jmap -histo 選項,該模式下不支持live子選項 |
-J< flag > | 傳遞指定參數給運行 jmap 的 JVM |
3. 基本示例
3.1 -heap 選項
jmap -heap 14480
使用以上命令查看 Java 進程 14480 的堆(heap)使用情況,打印如下信息
// 開啓了線程本地分配緩衝區(TLAB)
using thread-local object allocation.
// 並行 GC 收集算法,4 個線程
Parallel GC with 4 thread(s)
// 堆內存區域初始化配置
Heap Configuration:
// 對應jvm啓動參數-XX:MinHeapFreeRatio設置JVM堆最小空閒比率(default 40)
MinHeapFreeRatio = 0
// 設置JVM堆最大空閒比率(default 70)
MaxHeapFreeRatio = 100
// 對應jvm啓動參數-XX:MaxHeapSize= 設置JVM堆的最大大小
MaxHeapSize = 134217728 (128.0MB)
// 對應jvm啓動參數-XX:NewSize= 設置JVM堆‘新生代’的默認大小
NewSize = 42991616 (41.0MB)
// 對應jvm啓動參數-XX:MaxNewSize= 設置JVM堆的‘新生代’的最大大小
MaxNewSize = 44564480 (42.5MB)
// 對應jvm啓動參數-XX:OldSize= 設置JVM堆的‘老年代’的大小
OldSize = 87031808 (83.0MB)
// 對應jvm啓動參數-XX:NewRatio= 設置‘新生代’和‘老生代’的大小比率
NewRatio = 2
// 對應jvm啓動參數-XX:SurvivorRatio= 設置年輕代中Eden區與Survivor區的大小比值
SurvivorRatio = 8
// 對應jvm啓動參數-XX:MetaspaceSize= , Java 8 之後類相關信息存放在元空間(不屬於堆內存),此爲元空間初始化大小
MetaspaceSize = 21807104 (20.796875MB)
// 類指針壓縮空間大小, 默認爲1G。UseCompressedClassPointer 這個選項打開後,class信息中的指針也用 32bit
// 的 Compressed版本,而這些指針指向的空間被稱作“Compressed Class Space”。如果java程序引用了太多的包,
// 有可能會造成這個空間不夠用,於是會看到java.lang.OutOfMemoryError: Compressed class space 這時
// 一般調大CompreseedClassSpaceSize 就可以了,-XX:CompressedClassSpaceSize=
CompressedClassSpaceSize = 1073741824 (1024.0MB)
// 對應jvm啓動參數-XX:MaxMetaspaceSize= 設置元空間最大大小
MaxMetaspaceSize = 17592186044415 MB
// G1 收集器單個 region 的大小
G1HeapRegionSize = 0 (0.0MB)
Heap Usage:
// 年輕代內存使用情況
PS Young Generation
Eden Space:
capacity = 26214400 (25.0MB)
used = 16168040 (15.419044494628906MB)
free = 10046360 (9.580955505371094MB)
61.676177978515625% used
From Space:
capacity = 524288 (0.5MB)
used = 266000 (0.2536773681640625MB)
free = 258288 (0.2463226318359375MB)
50.7354736328125% used
To Space:
capacity = 524288 (0.5MB)
used = 0 (0.0MB)
free = 524288 (0.5MB)
0.0% used
// 年老代內存使用情況
PS Old Generation
capacity = 73400320 (70.0MB)
used = 73146256 (69.75770568847656MB)
free = 254064 (0.2422943115234375MB)
99.65386526925224% used
// 字符串常量池中的字符串信息
31347 interned Strings occupying 3713392 bytes.
3.2 -histo 選項
// 將對內存中類相關信息輸入到目標文件
jmap -histo 17134 > heap.log
// 查看該文件到前10行
head heap.log
jmap -histo
命令打印堆內存中的對象數量及其所佔內存的大小,通常這個列表會很大,終端界面不可能完全顯示,所以最好將其輸出到一個文件中,再查看這個文件即可。注意 jmap -histo:live
這個命令執行,JVM 會先觸發 Full GC,然後再統計信息
num #instances #bytes class name
編號 實例數量 佔用內存 類的名稱
----------------------------------------------
1: 90382 8994744 [C
2: 90151 2163624 java.lang.String
3: 63510 2032320 java.util.concurrent.ConcurrentHashMap$Node
4: 13058 1451536 java.lang.Class
5: 15017 1321496 java.lang.reflect.Method
6: 7809 1158504 [B
7: 19242 1153512 [Ljava.lang.Object;
- 輸出中 class name 非自定義類對照表
非自定義類 數據類型 B byte C char S short I int J long F float D double Z boolean [ 一維數組引用 L 類實例引用
3.3 -dump 選項
jmap -dump:live,format=b,file=dump 17134
這個命令執行,JVM會將整個 heap 的信息 dump 輸出到指定文件,如果 heap 比較大會導致這個過程比較耗時,並且執行的過程中爲了保證 dump 的信息是可靠的,JVM 會暫停程序運行。dump 文件生成後,可運行命令jhat -port 10086 dump
, 在瀏覽器中訪問 http://localhost:10086/
即可查看詳細信息