常用命令
jmap -heap PID
jmap -histo PID | head -20
jmap -dump:format=b,file=heap_dump.hprof PID
jmap
是 Java 开发工具包(JDK)提供的一个命令行工具,用于生成 Java 进程的内存映射信息。它可以帮助开发者分析 Java 堆内存的使用情况、生成堆转储文件(Heap Dump),以及查看类的内存分布等。
1. jmap 的作用
-
生成堆转储文件:将 Java 堆内存的快照保存到文件中,用于后续分析。
-
查看堆内存摘要:显示堆内存的使用情况,如对象数量、占用空间等。
-
查看类加载器信息:显示类加载器的统计信息。
-
查看永久代(PermGen)或元空间(Metaspace)信息:显示永久代或元空间的使用情况。
2. jmap 的使用方法
2.1 基本语法
bash
复制
jmap [options] <pid>
-
<pid>
:Java 进程的进程 ID。 -
[options]
:可选参数,用于控制输出内容或生成堆转储文件。
2.2 常用选项
-
-heap
:显示堆内存的摘要信息。 -
-histo
:显示堆内存中对象的直方图(按类和占用空间排序)。 -
-dump
:生成堆转储文件(Heap Dump)。 -
-finalizerinfo
:显示等待终结的对象信息。 -
-clstats
:显示类加载器的统计信息。 -
-F
:强制生成堆转储文件(适用于进程无响应的情况)。
3. 使用示例
3.1 获取 Java 进程的 PID
在生成堆转储文件之前,需要先获取 Java 进程的 PID。可以使用以下命令:
bash
复制
jps -l
输出示例:
复制
12345 com.example.Main 67890 sun.tools.jps.Jps
-
12345
是目标 Java 进程的 PID。
3.2 生成堆内存摘要
使用 -heap
选项显示堆内存的摘要信息:
bash
复制
jmap -heap 12345
输出示例:
复制
Attaching to process ID 12345, please wait... Debugger attached successfully. Server compiler detected. JVM version is 11.0.12+7using thread-local object allocation. Parallel GC with 4 thread(s)Heap Configuration:MinHeapFreeRatio = 40MaxHeapFreeRatio = 70MaxHeapSize = 1048576000 (1000.0MB)NewSize = 34865152 (33.25MB)MaxNewSize = 174587904 (166.5MB)OldSize = 699400192 (667.0MB)NewRatio = 2SurvivorRatio = 8MetaspaceSize = 21807104 (20.796875MB)CompressedClassSpaceSize = 1073741824 (1024.0MB)MaxMetaspaceSize = 17592186044415 MBG1HeapRegionSize = 0 (0.0MB)Heap Usage: PS Young Generation Eden Space:capacity = 268435456 (256.0MB)used = 268435456 (256.0MB)free = 0 (0.0MB)100.0% used From Space:capacity = 268435456 (256.0MB)used = 268435456 (256.0MB)free = 0 (0.0MB)100.0% used To Space:capacity = 268435456 (256.0MB)used = 0 (0.0MB)free = 268435456 (256.0MB)0.0% used PS Old Generationcapacity = 699400192 (667.0MB)used = 699400192 (667.0MB)free = 0 (0.0MB)100.0% used
3.3 生成对象直方图
使用 -histo
选项显示堆内存中对象的直方图:
bash
复制
jmap -histo 12345
输出示例:
复制
num #instances #bytes class name ----------------------------------------------1: 10000 10000000 java.lang.String2: 5000 5000000 java.util.HashMap$Node3: 2000 2000000 java.lang.Object
3.4 生成堆转储文件
使用 -dump
选项生成堆转储文件:
bash
复制
jmap -dump:format=b,file=heap_dump.hprof 12345
-
将堆转储文件保存为
heap_dump.hprof
。
3.5 强制生成堆转储文件
如果 Java 进程无响应,可以使用 -F
选项强制生成堆转储文件:
bash
复制
jmap -dump:format=b,file=heap_dump.hprof -F 12345
3.6 查看类加载器信息
使用 -clstats
选项显示类加载器的统计信息:
bash
复制
jmap -clstats 12345
4. 堆转储文件的分析
生成的堆转储文件(.hprof
)可以使用以下工具进行分析:
-
Eclipse MAT(Memory Analyzer Tool):功能强大的堆转储分析工具。
-
VisualVM:JDK 自带的图形化分析工具。
-
JProfiler:商业化的 Java 性能分析工具。
5. 使用场景
5.1 内存泄漏分析
-
通过堆转储文件分析对象的引用关系,找出内存泄漏的原因。
5.2 内存使用优化
-
查看堆内存中对象的分布,优化内存使用。
5.3 类加载器问题诊断
-
查看类加载器的统计信息,诊断类加载器相关的问题。
6. 总结
-
jmap
是 Java 开发者必备的诊断工具,用于生成堆转储文件和查看堆内存信息。 -
通过分析堆转储文件,可以诊断内存泄漏、优化内存使用等。
-
结合其他 JDK 工具(如
jps
、jstack
、jstat
),可以更全面地分析和调优 Java 应用程序。
通过掌握 jmap
的使用方法和堆转储文件的分析技巧,可以快速定位和解决 Java 应用程序的内存问题!
堆内存分析
根据你提供的 Heap Configuration(堆配置)信息,我们可以分析并解释各个参数的含义及其对 JVM 内存管理的影响。这里主要是关于堆内存、元空间和 G1 垃圾回收器的配置。
1. MinHeapFreeRatio = 40
- 含义:堆的最小空闲比例,表示堆的空闲内存比例不能低于该值,否则 JVM 会触发垃圾回收。值为
40
表示堆空闲内存的比例不能小于 40%。 - 影响:当堆的空闲空间低于此阈值时,JVM 会增加堆大小或进行垃圾回收来保证空闲空间不低于 40%。
2. MaxHeapFreeRatio = 70
- 含义:堆的最大空闲比例,表示堆的空闲内存比例不能超过该值。值为
70
表示堆空闲内存的比例不能超过 70%。 - 影响:如果堆的空闲空间超过此阈值,JVM 会缩小堆的大小,以优化内存使用。
3. MaxHeapSize = 1048576000 (1000.0MB)
- 含义:JVM 堆的最大大小,单位为字节。这里的
1048576000
字节等于 1000 MB。 - 影响:这是堆内存的上限,JVM 在运行过程中会尝试将堆的使用量控制在这个最大值之内。超出这个限制时,JVM 可能会触发垃圾回收或抛出
OutOfMemoryError
错误。
4. NewSize = 34865152 (33.25MB)
- 含义:年轻代(Young Generation)的初始大小。值为
34865152
字节,即 33.25MB。 - 影响:年轻代内存初始时分配为 33.25MB。这个值会影响到年轻代垃圾回收的频率和效率。较小的年轻代可能会导致更频繁的垃圾回收。
5. MaxNewSize = 174587904 (166.5MB)
- 含义:年轻代的最大大小。值为
174587904
字节,即 166.5MB。 - 影响:年轻代内存的最大容量为 166.5MB。超出这个大小后,JVM 会在年轻代内存达到最大值时进行垃圾回收。
6. OldSize = 699400192 (667.0MB)
- 含义:老年代(Old Generation)的初始大小。值为
699400192
字节,即 667MB。 - 影响:初始的老年代大小为 667MB。如果老年代空间满了,会触发 Full GC(完全垃圾回收)。
7. NewRatio = 2
- 含义:年轻代与老年代内存的大小比例。值为
2
表示年轻代的内存大小是老年代的 1/2。 - 影响:该配置影响了年轻代和老年代的内存比例。较大的
NewRatio
值意味着年轻代较小,反之则意味着年轻代较大。年轻代过小可能导致频繁的年轻代 GC。
8. SurvivorRatio = 8
- 含义:Survivor 区域之间的内存大小比例。表示每个 Survivor 区的大小是 Eden 区的 1/8。
- 影响:较小的 Survivor 区会导致对象较快地进入老年代,而较大的 Survivor 区则可能延迟对象进入老年代。合理的 Survivor 区大小有助于减少对象晋升到老年代的频率。
9. MetaspaceSize = 21807104 (20.8MB)
- 含义:元空间(Metaspace)的初始大小。值为
21807104
字节,即 20.8MB。 - 影响:元空间用于存放类元数据(类的结构信息)。JVM 会根据需要动态调整该空间的大小,但初始值为 20.8MB。
10. CompressedClassSpaceSize = 1073741824 (1024.0MB)
- 含义:Compressed Class Space 的大小,通常为 1GB(1024MB)。该空间用于存储类的压缩形式,提高内存效率。
- 影响:在启用了压缩类指针时,类的元数据会存放在该区域。较大的
CompressedClassSpaceSize
提高了对大规模类加载的支持。
11. MaxMetaspaceSize = 17592186044415 MB
- 含义:元空间的最大大小。值为
17592186044415
MB,几乎是无限大(这是一个非常大的数字,理论上表示没有限制)。 - 影响:这意味着元空间的最大大小几乎没有限制,JVM 可以根据需要动态扩展元空间,直到系统内存耗尽为止。
12. G1HeapRegionSize = 0 (0.0MB)
- 含义:G1 垃圾回收器的堆区域大小。值为
0
表示没有启用 G1 垃圾回收器。 - 影响:G1 回收器的堆区域大小设置为
0
,意味着该 JVM 配置并没有使用 G1 垃圾回收器(可能使用的是默认的垃圾回收策略,如 Parallel GC 或 CMS)。
总结:
- 堆内存管理:堆的最大大小为 1GB,其中年轻代和老年代的比例是 2:1,且年轻代的初始大小为 33.25MB,最大为 166.5MB。通过
MinHeapFreeRatio
和MaxHeapFreeRatio
来控制堆的空闲内存比例,保持合理的内存使用。 - 元空间:元空间的初始大小为 20.8MB,并且最大值几乎无限制,允许 JVM 动态扩展元空间以存储类元数据。
- 垃圾回收器:从配置来看,这个 JVM 可能没有启用 G1 垃圾回收器(
G1HeapRegionSize = 0
),而是可能使用其他垃圾回收策略。
这些配置影响了 JVM 的内存管理策略、垃圾回收频率以及程序的性能。合理的堆内存配置可以提高 JVM 应用程序的性能,减少垃圾回收的停顿时间。