使用 jmap 分析JVM内存状态
前言 heap 查看整个JVM内存状态
打印 heap 的概要信息,GC使用的算法,heap 的配置和使用情况,可以用此来判断内存目前的使用情况以及垃圾回收情况。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 > jmap -heap 1234 Attaching to process ID 13497, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.201-b09 using thread-local object allocation. Parallel GC with 2 thread(s) Heap Configuration: MinHeapFreeRatio = 0 MaxHeapFreeRatio = 100 MaxHeapSize = 1048576000 (1000.0MB) NewSize = 87031808 (83.0MB) MaxNewSize = 349175808 (333.0MB) OldSize = 175112192 (167.0MB) NewRatio = 2 SurvivorRatio = 8 MetaspaceSize = 21807104 (20.796875MB) CompressedClassSpaceSize = 1073741824 (1024.0MB) MaxMetaspaceSize = 17592186044415 MB G1HeapRegionSize = 0 (0.0MB) Heap Usage: PS Young Generation Eden Space: capacity = 35127296 (33.5MB) used = 31401816 (29.947105407714844MB) free = 3725480 (3.5528945922851562MB) 89.39434450064132% used From Space: capacity = 524288 (0.5MB) used = 131072 (0.125MB) free = 393216 (0.375MB) 25.0% used To Space: capacity = 524288 (0.5MB) used = 0 (0.0MB) free = 524288 (0.5MB) 0.0% used PS Old Generation capacity = 92798976 (88.5MB) used = 11140584 (10.624488830566406MB) free = 81658392 (77.8755111694336MB) 12.005072124933791% used 12155 interned Strings occupying 1063376 bytes.
histo 查看JVM堆中对象详细占用情况
打印堆的对象统计,包括对象数、内存大小等。jmap -histo:live 这个命令执行,JVM会先触发gc,然后再统计信息。
列对应信息为编号id、实例个数、所有实例大小、类名
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 > jmap -histo 783 num #instances #bytes class name ---------------------------------------------- 1: 286511 9516456 [Ljava.lang.Object; 2: 113692 9458248 [C 3: 31510 6249248 [B 4: 132529 4240928 java.io.ObjectStreamClass$WeakClassKey 5: 95868 3834720 java.util.TreeMap$Entry 6: 14097 3740048 [I 7: 60312 1447488 java.lang.String 8: 25273 1213104 java.util.HashMap 9: 46425 1114200 java.lang.Long 10: 10056 1045824 java.io.ObjectStreamClass 11: 10429 500592 java.util.TreeMap 12: 7332 470824 [Ljava.util.Hashtable$Entry; 13: 14637 468384 java.util.Vector 14: 4609 442464 java.lang.management.ThreadInfo 15: 12704 406528 java.util.TreeMap$KeyIterator 16: 15719 377256 java.io.SerialCallbackContext 17: 7325 351600 java.util.Hashtable
dump dump堆到文件,format指定输出格式,live指明是活着的对象,file指定文件名
1 > jmap -dump:live,format=b,file=/lihm.hprof 129665
这个命令执行,JVM会将整个heap的信息dump写入到一个文件,heap如果比较大的话,就会导致这个过程比较耗时,并且执行的过程中为了保证dump的信息是可靠的,所以会暂停应用, 线上系统慎用。
lihm.hprof 为二进制文件,less
命令查看不了,得用分析工具分析,比如jhat、MAT
jhat 查看
1 2 3 4 5 6 7 8 9 10 > jhat -J-Xmx1024M lihm.hprof Reading from lihm.txt... Dump file created Thu Oct 24 16:26:47 CST 2019 Snapshot read, resolving... Resolving 104381 objects... Chasing references, expect 20 dots.................... Eliminating duplicate references.................... Snapshot resolved. Started HTTP server on port 7000 Server is ready.
访问7000端口, 可以统计实例总数、占用大小
MAT工具的下载和安装
MAT(Memory Analyzer Tool)工具是eclipse的一个插件(MAT也可以单独使用),使用起来非常方便,尤其是在分析大内存的dump文件时,可以非常直观的看到各个对象在堆空间中所占用的内存大小、类实例数量、对象引用关系、利用OQL对象查询,以及可以很方便的找出对象GC Roots的相关信息,当然最吸引人的还是能够快速为开发人员生成内存泄露报表,方便定位问题和分析问题。
MAT工具的下载地址 , 具体参考Java内存分析工具MAT(Memory Analyzer Tool)安装使用实例
-F 强制模式。如果指定的pid没有响应,请使用jmap -dump或jmap -histo选项。此模式下,不支持live子选项。
参考链接