使用jmap -heap pid查看进程堆内存使用情况,包括使用的GC算法、堆配置参数和各代中堆内存使用情况。比如下面的例子:
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 49 | root@ubuntu:/ # jmap -heap 21711 Attaching to process ID 21711, please wait... Debugger attached successfully. Server compiler detected. JVM version is 20.10-b01 using thread- local object allocation. Parallel GC with 4 threads) Heap Configuration: MinHeapFreeRatio = 40 MaxHeapFreeRatio = 70 MaxHeapSize = 2067791872 1972.0MB) NewSize = 1310720 1.25MB) MaxNewSize = 17592186044415 MB OldSize = 5439488 5.1875MB) NewRatio = 2 SurvivorRatio = 8 PermSize = 21757952 20.75MB) MaxPermSize = 85983232 82.0MB) Heap Usage: PS Young Generation Eden Space: capacity = 6422528 6.125MB) used = 5445552 5.1932830810546875MB) free = 976976 0.9317169189453125MB) 84.78829520089286% used From Space: capacity = 131072 0.125MB) used = 98304 0.09375MB) free = 32768 0.03125MB) 75.0% used To Space: capacity = 131072 0.125MB) used = 0 0.0MB) free = 131072 0.125MB) 0.0% used PS Old Generation capacity = 35258368 33.625MB) used = 4119544 3.9287033081054688MB) free = 31138824 29.69629669189453MB) 11.683876009235595% used PS Perm Generation capacity = 52428800 50.0MB) used = 26075168 24.867218017578125MB) free = 26353632 25.132781982421875MB) 49.73443603515625% used .... |
使用jmap -histo[:live] pid查看堆内存中的对象数目、大小统计直方图,如果带上live则只统计活对象,如下:
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 | root@ubuntu:/ # jmap -histo:live 21711 | more num #instances #bytes class name ---------------------------------------------- 1: 38445 5597736 <constMethodKlass> 2: 38445 5237288 <methodKlass> 3: 3500 3749504 <constantPoolKlass> 4: 60858 3242600 <symbolKlass> 5: 3500 2715264 <instanceKlassKlass> 6: 2796 2131424 <constantPoolCacheKlass> 7: 5543 1317400 [I 8: 13714 1010768 [C 9: 4752 1003344 [B 10: 1225 639656 <methodDataKlass> 11: 14194 454208 java.lang.String 12: 3809 396136 java.lang.Class 13: 4979 311952 [S 14: 5598 287064 [[I 15: 3028 266464 java.lang.reflect.Method 16: 280 163520 <objArrayKlassKlass> 17: 4355 139360 java.util.HashMap$Entry 18: 1869 138568 [Ljava.util.HashMap$Entry; 19: 2443 97720 java.util.LinkedHashMap$Entry 20: 2072 82880 java.lang.ref.SoftReference 21: 1807 71528 [Ljava.lang.Object; 22: 2206 70592 java.lang.ref.WeakReference 23: 934 52304 java.util.LinkedHashMap 24: 871 48776 java.beans.MethodDescriptor 25: 1442 46144 java.util.concurrent.ConcurrentHashMap$HashEntry 26: 804 38592 java.util.HashMap 27: 948 37920 java.util.concurrent.ConcurrentHashMap$Segment 28: 1621 35696 [Ljava.lang.Class; 29: 1313 34880 [Ljava.lang.String; 30: 1396 33504 java.util.LinkedList$Entry 31: 462 33264 java.lang.reflect.Field 32: 1024 32768 java.util.Hashtable$Entry 33: 948 31440 [Ljava.util.concurrent.ConcurrentHashMap$HashEntry; |
class name是对象类型,说明如下:
1 2 3 4 5 6 7 8 9 | B byte C char D double F float I int J long Z boolean [ 数组,如[I表示int[] [L+类名 其他对象 |
还有一个很常用的情况是:用jmap把进程内存使用情况dump到文件中,再用jhat分析查看。jmap进行dump命令格式如下:
1 | jmap -dump: format =b, file =dumpFileName pid |
我一样地对上面进程ID为21711进行Dump:
1 2 3 | root@ubuntu:/ # jmap -dump:format=b,file=/tmp/dump.dat 21711 Dumping heap to /tmp/dump .dat ... Heap dump file created |
dump出来的文件可以用MAT、VisualVM等工具查看,这里用jhat查看:
1 2 3 4 5 6 7 8 9 10 | root@ubuntu:/ # jhat -port 9998 /tmp/dump.dat Reading from /tmp/dump .dat... Dump file created Tue Jan 28 17:46:14 CST 2014 Snapshot read , resolving... Resolving 132207 objects... Chasing references, expect 26 dots.......................... Eliminating duplicate references.......................... Snapshot resolved. Started HTTP server on port 9998 Server is ready. |