共计 7070 个字符,预计需要花费 18 分钟才能阅读完成。
jmap 命令能够获取运行中的 jvm 的快照, 从而离线剖析, 查看内存透露, 查看一些重大影响性能的大对象的创立, 查看零碎中最多的对象, 各种对象所占用的内存大小. 能够应用 jmap 生成 Heap Dump.
什么是堆 Dump
堆 Dump 是反馈 Java 堆应用状况的内存镜像, 其中次要蕴含零碎信息, 虚拟机属性, 残缺的线程 Dump, 所有类和对象的状态等。个别,在内存不足,GC 异样等状况下, 咱们就会狐疑内存透露, 这个时候就能够制作堆 (Dump) 来查问具体情况。
常见的内存谬误
> outOfMemoryError 年轻代内存不足。> outOfMemoryError:PermGen Space 永恒代内存不足。> outOfMemoryError:GC overhead limit exceed 垃圾回收工夫占用零碎运行工夫的 98% 或以上。
jmap -heap pid
查看 java 堆信息
Attaching to process ID 18378, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.261-b12
using thread-local object allocation.
Parallel GC with 4 thread(s)
Heap Configuration:
MinHeapFreeRatio = 0 # JVM 最小闲暇比率
MaxHeapFreeRatio = 100
MaxHeapSize = 4164943872 (3972.0MB)
NewSize = 87031808 (83.0MB)
MaxNewSize = 1388314624 (1324.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 = 1314914304 (1254.0MB)
used = 794405392 (757.6040191650391MB)
free = 520508912 (496.39598083496094MB)
60.41499355383087% used
From Space:
capacity = 36175872 (34.5MB)
used = 23758320 (22.657699584960938MB)
free = 12417552 (11.842300415039062MB)
65.6744915506114% used
To Space:
capacity = 37224448 (35.5MB)
used = 0 (0.0MB)
free = 37224448 (35.5MB)
0.0% used
PS Old Generation
capacity = 352321536 (336.0MB)
used = 206117376 (196.56884765625MB)
free = 146204160 (139.43115234375MB)
58.502633231026785% used
应用了
Parallel GC
垃圾收集器
- MinHeapFreeRatio 参数用来设置堆空间最小闲暇比例,默认值是 0。当堆空间的闲暇内存小于这个数值时,JVM 便会扩大堆空间。
- MaxHeapFreeRatio 参数用来设置堆空间最大闲暇比例,默认值是 100。当堆空间的闲暇内存大于这个数值时,便会压缩堆空间,失去一个较小的堆。
当 -Xmx 和 -Xms 相等时 MinHeapFreeRatio 和 MaxHeapFreeRatio 两个参数有效。
- MaxHeapSize 最大堆内存 3972MB
- NewSize 新生代默认大小 83MB
- MaxNewSize 新生代最大大小为 1324MB
- OldSize 老年代大小 167MB
- NewRatio 新生代和老年代的大小比率 2
- SurvivorRatio 年老代中 Eden 和 Survivor 的比率 8
- MetaspaceSize 元空间大小 20.796875MB
- CompressedClassSpaceSize 如果开启了 -XX:+UseCompressedOops 及 -XX:+UseCompressedClassesPointers(默认是开启),则 UseCompressedOops 会应用 32-bit 的 offset 来代表 java object 的援用,而 UseCompressedClassPointers 则应用 32-bit 的 offset 来代表 64-bit 过程中的 class pointer;能够应用 CompressedClassSpaceSize 来设置这块的空间大小
- MaxMetaspaceSize 最大元空间大小 1073741824
- G1HeapRegionSize G1 收集器启用, 一个 Region 的大小能够通过参数 -XX:G1HeapRegionSize 设定,取值范畴从 1M 到 32M,且是 2 的指数。
jmap pid
查看过程的内存映像信息, 相似 Solaris pmap 命令
应用不带选项参数的 jmap 打印共享对象映射,将会打印指标虚拟机中加载的每个共享对象的起始地址、映射大小以及共享对象文件的门路全称。这与 Solaris 的 pmap 工具比拟类似。
[root@rumenz ~]# jmap 18378
Attaching to process ID 18378, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.261-b12
0x000056248b911000 8K /usr/local/jdk1.8/bin/java
0x00007f35f8b2e000 487K /usr/local/jdk1.8/jre/lib/amd64/libfontmanager.so
0x00007f35f8d91000 38K /usr/local/jdk1.8/jre/lib/amd64/libawt_headless.so
0x00007f35f8f99000 741K /usr/local/jdk1.8/jre/lib/amd64/libawt.so
0x00007f35f9669000 86K /usr/lib64/libgcc_s-4.8.5-20150702.so.1
0x00007f35f987f000 276K /usr/local/jdk1.8/jre/lib/amd64/libsunec.so
0x00007f36189ed000 110K /usr/local/jdk1.8/jre/lib/amd64/libnet.so
0x00007f3618c04000 91K /usr/local/jdk1.8/jre/lib/amd64/libnio.so
0x00007f361991f000 50K /usr/local/jdk1.8/jre/lib/amd64/libmanagement.so
0x00007f363caee000 124K /usr/local/jdk1.8/jre/lib/amd64/libzip.so
0x00007f363cd0a000 60K /usr/lib64/libnss_files-2.17.so
0x00007f363cf1d000 226K /usr/local/jdk1.8/jre/lib/amd64/libjava.so
0x00007f363d14c000 64K /usr/local/jdk1.8/jre/lib/amd64/libverify.so
0x00007f363d35b000 42K /usr/lib64/librt-2.17.so
0x00007f363d563000 1110K /usr/lib64/libm-2.17.so
0x00007f363d865000 16698K /usr/local/jdk1.8/jre/lib/amd64/server/libjvm.so
0x00007f363e85a000 2105K /usr/lib64/libc-2.17.so
0x00007f363ec28000 18K /usr/lib64/libdl-2.17.so
0x00007f363ee2c000 106K /usr/local/jdk1.8/lib/amd64/jli/libjli.so
0x00007f363f044000 138K /usr/lib64/libpthread-2.17.so
0x00007f363f260000 159K /usr/lib64/ld-2.17.so
jmap -histo:live pid
堆中对象统计
其中包含每个 Java 类、对象数量、内存大小 (单位:字节)、齐全限定的类名。打印的虚拟机外部的类名称将会带有一个*
前缀。如果指定了 live 子选项,则只计算流动的对象。
[root@Server-i-b2l6uawirw ~]# jmap -histo:live 18378 | more
num #instances #bytes class name
----------------------------------------------
1: 221097 19915168 [C
2: 220601 5294424 java.lang.String
3: 44932 3954016 java.lang.reflect.Method
4: 67973 3769400 [Ljava.lang.Object;
5: 98145 3140640 java.util.HashMap$Node
6: 115945 2782680 java.util.concurrent.atomic.AtomicLong
7: 19301 2126520 java.lang.Class
8: 61752 1976064 java.util.concurrent.ConcurrentHashMap$Node
9: 14120 1665080 [Ljava.util.HashMap$Node;
10: 8997 1548592 [B
11: 15452 1236160 com.google.common.cache.LocalCache$Segment
12: 34289 1097248 java.util.Hashtable$Entry
13: 37325 895800 java.util.ArrayList
14: 2899 790728 [Z
15: 49080 785280 java.lang.Object
16: 19315 772600 com.google.common.cache.AbstractCache$SimpleStatsCounter
17: 21096 675072 java.lang.ref.WeakReference
18: 16237 649480 java.lang.ref.SoftReference
19: 13368 641664 java.util.HashMap
20: 15945 637800 java.util.LinkedHashMap$Entry
21: 114 588392 [F
22: 18238 583616 java.util.concurrent.locks.ReentrantLock$NonfairSync
23: 486 533312 [Ljava.util.concurrent.ConcurrentHashMap$Node;
24: 16521 528672 java.lang.ref.ReferenceQueue
25: 6928 498816 java.lang.reflect.Field
26: 3863 494464 com.google.common.cache.LocalCache
27: 7680 491520 java.net.URL
28: 5948 475840 java.lang.reflect.Constructor
29: 8359 463928 [I
[B 代表 byte
[C 代表 char
[D 代表 double
[F 代表 float
[I 代表 int
[J 代表 long
[Z 代表 boolean
jmap -clstats pid
打印类加载信息
-clstats 是 -permstat 的代替计划,在 JDK8 之前,-permstat 用来打印类加载器的数据
打印 Java 堆内存的永恒保留区域的类加载器的智能统计信息。对于每个类加载器而言,它的名称、活跃度、地址、父类加载器、它所加载的类的数量和大小都会被打印。此外,蕴含的字符串数量和大小也会被打印。
[root@rumenz ~]# jmap -clstats 18378
Attaching to process ID 18378, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.261-b12
finding class loader instances ..
done.
computing per loader stat ..done.
please wait.. computing liveness.liveness analysis may be inaccurate ...
class_loader classes bytes parent_loader alive? type
<bootstrap> 3365 5881890 null live <internal>
0x00000006cb8abb88 1 880 0x00000006c7c2a4c8 dead sun/reflect/DelegatingClassLoader@0x00000007c000a0a0
0x00000006cafd0af0 1 878 0x00000006c8520248 dead sun/reflect/DelegatingClassLoader@0x00000007c000a0a0
0x00000006c8600870 0 0 0x00000006c82362b8 dead hudson/ClassicPluginStrategy$DependencyClassLoader@0x00000007c0275308
0x00000006c86a9878 81 74744 0x00000006c86a98e8 dead hudson/ClassicPluginStrategy$AntClassLoader2@0x00000007c0274dc8
0x00000006ca739a60 1 880 0x00000006c7c2a4c8 dead sun/reflect/DelegatingClassLoader@0x00000007c000a0a0
0x00000006cafceae8 1 880 0x00000006c7c2a4c8 dead sun/reflect/DelegatingClassLoader@0x00000007c000a0a0
0x00000006cb541b40 1 880 0x00000006c7c2a4c8 dead sun/reflect/DelegatingClassLoader@0x00000007c000a0a0
0x00000006cb75fb68 1 880 0x00000006c86b09b8 dead sun/reflect/DelegatingClassLoader@0x00000007c000a0a0
0x00000006ca5f9a40 1 1474 null dead sun/reflect/DelegatingClassLoader@0x00000007c000a0a0
0x00000006cb07fb18 1 880 0x00000006c82bcba8 dead sun/reflect/DelegatingClassLoader@0x00000007c000a0a0
0x00000006cb083b28 1 1474 0x00000006c7c2a4c8 dead sun/reflect/DelegatingClassLoader@0x00000007c000a0a0
0x00000006c86ad848 8 8716 0x00000006c86ad8b8 dead hudson/ClassicPluginStrategy$AntClassLoader2@0x00000007c0274dc8
0x00000006c8bde898 49 155511 0x00000006c8237a80 dead com/google/inject/internal/BytecodeGen$BridgeClassLoader@0x00000007c05f9028
jmap -dump:format=b,file=dump.phrof pid
生成堆转储快照文件
这个命令执行,JVM 会将整个 heap 的信息 dump 写入到一个文件,heap 如果比拟大的话,就会导致这个过程比拟耗时,并且执行的过程中为了保障 dump 的信息是牢靠的,所以会暂停利用,线上零碎慎用。
[root@rumenz ~]# jmap -dump:format=b,file=dump.hprof 18378
Dumping heap to /root/dump.hprof ...
Heap dump file created