命令 jmap 查看内存使用情况

简介

jmap(Java Virtual Machine Memory Map)是JDK提供的一个可以生成Java虚拟机的堆转储快照dump文件的命令行工具。除此以外,jmap命令还可以查看finalize执行队列、Java堆和方法区的详细信息,比如空间使用率、当前使用的什么垃圾回收器、分代情况等等。

语法

1
2
3
4
5
6
7
8
9
10
jmap [options] pid

命令参数说明:
option:jmap命令的可选参数。如果没有指定这个参数,jinfo命令会显示Java虚拟机进程的内存映像信息。常用的 option 如下:
- heap 显示 Java 堆详细信息
- histo 显示堆中对象的统计信息
- permstat 显示堆永久区的类加载器的统计信息
- finalizerinfo 显示在 F-Queue 队列等待 Finalizer 线程执行 finalize 方法的对象
- dump 生成堆转储快照
pid:要打印配置信息的Java虚拟机的进程ID。

示例

jmap -heap 查看内存使用情况

jmap -heap 命令通常用于诊断和调试 Java 应用程序的内存问题,例如内存泄漏内存溢出等。

通过 jmap -heap 命令获取到的堆内存信息可以帮助开发人员更加全面地了解 Java 应用程序的内存使用情况,找出内存问题的根本原因,并进行相应的优化和改进。在使用 jmap -heap 命令时,需要注意以下几点:

  1. jmap -heap 命令会暂停 Java 进程的执行并进行内存快照,可能会对应用程序的性能产生一定的影响。
  2. jmap -heap 命令只能用于 HotSpot 虚拟机,不适用于其他虚拟机实现。
  3. jmap -heap 命令可能会产生较大的输出,建议将输出重定向到文件中以便后续分析。

它包含以下参数:

  1. -dump:导出 Java 堆内存中的内容到文件中。
  2. -file:指定导出文件的文件名,如果不指定则默认为 java_pid[进程 ID].hprof
  3. -F:强制执行指令,即使 JVM 正在退出或者已经退出。
  4. -histo:打印 Java 堆内存中各个对象类型的实例数目和大小。
  5. -J:传递参数给 JVM,例如“-J-Xms512m”。
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
[lepeng@centos ~]# jmap -heap 24126
Attaching to process ID 24126, please wait... # 表示 jmap 正在尝试连接并附加到一个进程ID为 24126 的Java进程
Debugger attached successfully. # 表示 jmap 已经成功附加到了该进程并成功连接了调试器
Server compiler detected. # 表示该 Java 进程正在运行 Server 模式的编译器
JVM version is 25.121-b13 # 表示该 Java 程序的版本号为 25.121-b13

using thread-local object allocation. # 表示 Java 进程正在使用线程本地对象分配的方式
Parallel GC with 4 thread(s) # 表示 Java 进程正在使用 4 个线程来进行并行垃圾回收

# 堆内存配置信息
Heap Configuration:
MinHeapFreeRatio = 0 # 表示在堆内存达到最大值之前,堆内存中不允许有任何自由空间
MaxHeapFreeRatio = 100 # 表示在堆内存达到最大值之后,堆内存中允许全部是自由空间
MaxHeapSize = 5368709120 (5120.0MB) # 表示堆内存的最大容量为 5GB
NewSize = 2684354560 (2560.0MB) # 表示新生代(Young Generation)的初始容量为 2.5GB
MaxNewSize = 2684354560 (2560.0MB) # 表示新生代的最大容量为 2.5GB
OldSize = 2684354560 (2560.0MB) # 表示老年代(Old Generation)的初始容量为 2.5GB
NewRatio = 1 # 表示新生代与老年代内存大小的比例为 1:1
SurvivorRatio = 8 # 表示 Eden 区域与 Survivor 区域之间内存大小的比例为 8:1
MetaspaceSize = 21807104 (20.796875MB) # 表示元数据区域的大小为 20.8MB
CompressedClassSpaceSize = 1073741824 (1024.0MB) # 表示压缩类空间的大小为 1GB
MaxMetaspaceSize = 17592186044415 MB # 表示元数据区域的最大容量为 16 EB(exabytes)
G1HeapRegionSize = 0 (0.0MB) # 表示 G1 垃圾回收器使用的内存段的大小为 0

# 堆内存的使用情况
Heap Usage:
PS Young Generation # 表示使用了 Parallel Scavenge(PS)年轻代内存的信息
Eden Space: # 表示 Eden 区域的使用情况
capacity = 1009254400 (962.5MB) # 表示 Eden 区域的最大容量为 962.5MB
used = 474955488 (452.9528503417969MB) # 表示 Eden 区域已使用的内存大小为 452.95MB
free = 534298912 (509.5471496582031MB) # 表示 Eden 区域尚未使用的内存大小为 509.55MB
47.06003639914773% used
From Space: # 表示 Survivor 0 区域的使用情况
capacity = 834142208 (795.5MB) # 表示 Survivor 0 区域的最大容量为 795.5MB
used = 326834600 (311.69376373291016MB) # 表示 Survivor 0 区域已使用的内存大小为 311.69MB
free = 507307608 (483.80623626708984MB) # 表示 Survivor 0 区域尚未使用的内存大小为 483.81MB
39.182119891000646% used
To Space: # 表示 Survivor 1 区域的使用情况
capacity = 793247744 (756.5MB) # 表示 Survivor 1 区域的最大容量为 756.5MB
used = 0 (0.0MB) # 表示 Survivor 1 区域尚未使用任何内存
free = 793247744 (756.5MB) # 表示 Survivor 1 区域尚未使用的内存大小为 756.5MB
0.0% used
PS Old Generation # 表示使用了 Parallel Scavenge(PS)老年代内存的信息
capacity = 2684354560 (2560.0MB) # 表示老年代的最大容量为 2.5GB
used = 1371482032 (1307.9471893310547MB) # 表示老年代已使用的内存大小为 1307.95MB
free = 1312872528 (1252.0528106689453MB) # 表示老年代尚未使用的内存大小为 1252.05MB
51.091687083244324% used # 表示老年代已使用内存占总内存的比例为 51.09%

53559 interned Strings occupying 6180024 bytes.

-histo[:live] 查看内存中对象数量及大小

显示Java堆中对象的统计信息,包括:对象数量、占用内存大小(单位:字节)和类的完全限定名

1
2
3
4
5
# 查看所有对象,包括活跃以及非活跃的
jmap -histo <pid> | more

# 查看活跃对象
jmap -histo:live <pid> | more

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[lepeng@centos ~]# jmap -histo:live 43616 | more
num #instances #bytes class name
----------------------------------------------
1: 5734 739488 <methodKlass>
2: 5734 662424 <constMethodKlass>
3: 380 453824 <constantPoolKlass>
4: 349 279520 <constantPoolCacheKlass>
5: 1834 264656 [C
6: 380 257248 <instanceKlassKlass>
7: 528 89504 [B
8: 443 54200 java.lang.Class
9: 627 41648 [[I
10: 1683 40392 java.lang.String
11: 580 35536 [S
12: 785 31400 java.util.TreeMap$Entry
13: 46 24656 <objArrayKlassKlass>
14: 314 13184 [Ljava.lang.Object;
15: 186 7584 [Ljava.lang.String;
16: 13 6152 <methodDataKlass>
17: 8 4288 <typeArrayKlassKlass>
18: 112 3584 java.util.Hashtable$Entry
19: 11 2288 <klassKlass>
20: 61 1952 java.util.concurrent.ConcurrentHashMap$HashEntry
21: 38 1824 sun.util.locale.LocaleObjectCache$CacheEntry

对象说明

  • B byte
  • C char
  • D double
  • F float
  • I int
  • J long
  • Z boolean
  • [ 数组,如[I表示int[]
  • [L+类名 其他对象

-dump 将内存使用情况dump到文件中

有些时候我们需要将jvm当前内存中的情况dump到文件中,然后对它进行分析,jmap也是支持dump到文件中的

1
2
3
4
5
6
7
# 用法:
jmap -dump:[live,]format=b,file=dumpFileName <pid>

具体说明如下:
live参数是可选的,如果指定,则只转储堆中的活动对象;如果没有指定,则转储堆中的所有对象。
format=b表示以hprof二进制格式转储Java堆的内存。
file=<filename>用于指定快照dump文件的文件名。

示例

1
jmap -dump:format=b,file=/tmp/dump.dat 6219

命令 jmap 查看内存使用情况
https://flepeng.github.io/021-Java-42-JVM-命令-jmap-查看内存使用情况/
作者
Lepeng
发布于
2024年4月19日
许可协议