Java 的 jmap 命令使用总结

jmap 命令简介

jmap(Java Virtual Machine Memory Map)是 JDK 提供的一个可以生成 Java 虚拟机的堆转储快照 dump 文件的命令行工具。

查看进程 ID

通过 ps 命令查询进程 ID

ps x

通过 jps 命令查询进程 ID

jps

查看内存使用情况

jmap -heap <pid>

示例:

$ jmap -heap 14
Attaching to process ID 14, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.232-b09

using thread-local object allocation.
Parallel GC with 2 thread(s)

Heap Configuration:
   MinHeapFreeRatio         = 0
   MaxHeapFreeRatio         = 100
   MaxHeapSize              = 10737418240 (10240.0MB)
   NewSize                  = 3578789888 (3413.0MB)
   MaxNewSize               = 3578789888 (3413.0MB)
   OldSize                  = 7158628352 (6827.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 = 2975858688 (2838.0MB)
   used     = 1685950048 (1607.8472595214844MB)
   free     = 1289908640 (1230.1527404785156MB)
   56.65423747432996% used
From Space:
   capacity = 185597952 (177.0MB)
   used     = 185437328 (176.84681701660156MB)
   free     = 160624 (0.1531829833984375MB)
   99.91345594158281% used
To Space:
   capacity = 305135616 (291.0MB)
   used     = 0 (0.0MB)
   free     = 305135616 (291.0MB)
   0.0% used
PS Old Generation
   capacity = 7158628352 (6827.0MB)
   used     = 120601488 (115.01454162597656MB)
   free     = 7038026864 (6711.985458374023MB)
   1.684701063805135% used

28573 interned Strings occupying 3120360 bytes.

heap 结果说明

  • MinHeapFreeRatio

    空闲堆空间的最小百分比,计算公式为:HeapFreeRatio =(CurrentFreeHeapSize/CurrentTotalHeapSize) * 100,值的区间为 0 到 100,默认值为 40。如果 HeapFreeRatio < MinHeapFreeRatio,则需要进行堆扩容,扩容的时机应该在每次垃圾回收之后。

  • MaxHeapFreeRatio

    空闲堆空间的最大百分比,计算公式为:HeapFreeRatio =(CurrentFreeHeapSize/CurrentTotalHeapSize) * 100,值的区间为 0 到 100,默认值为 70。如果 HeapFreeRatio > MaxHeapFreeRatio,则需要进行堆缩容,缩容的时机应该在每次垃圾回收之后。

  • MaxHeapSize

    JVM 堆空间允许的最大值。

  • NewSize

    JVM 新生代堆空间的默认值。

  • MaxNewSize

    JVM 新生代堆空间允许的最大值。

  • OldSize

    JVM 老年代堆空间的默认值。

  • NewRatio

    新生代(2 个 Survivor 区和 Eden 区 )与老年代(不包括永久区)的堆空间比值,表示新生代:老年代 = 1:2。

  • SurvivorRatio

    两个 Survivor 区和 Eden 区的堆空间比值为 8,表示 S0 : S1 :Eden = 1:1:8。

  • MetaspaceSize

    JVM 元空间的默认值。

  • CompressedClassSpaceSize

    Compressed Class Space 空间大小限制

  • MaxMetaspaceSize

    JVM 元空间允许的最大值。

  • G1HeapRegionSize

    在使用 G1 垃圾回收算法时,JVM 会将 Heap 空间分隔为若干个 Region,该参数用来指定每个 Region 空间的大小。

查看内存中对象数量及大小

查看所有对象,包括活跃以及非活跃的:

$ jmap -histo <pid> | more 

查看活跃对象:

$ jmap -histo:live <pid> | more

示例:

$ jmap -histo 37761 | more
 num     #instances         #bytes  class name
----------------------------------------------
   1:           691        9012192  [I
   2:          2850        1785160  [B
   3:         12393        1630216  [C
   4:          8772        1398816  <constMethodKlass>
   5:          8772        1198336  <methodKlass>

查看类加载器的统计信息

显示 Java 堆中元空间的类加载器的统计信息:

jmap -clstats <pid>

示例:

$ jmap -clstats 14
Attaching to process ID 14, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.232-b09
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>     3382    5921609   null          live    <internal>
0x000000054201ac00      1       1457    0x0000000540013560      dead    sun/reflect/DelegatingClassLoader@0x00000007c0009c70
0x0000000542826080      1       864     0x0000000540013560      dead    sun/reflect/DelegatingClassLoader@0x00000007c0009c70
0x000000054282ba80      1       864     0x0000000540013560      dead    sun/reflect/DelegatingClassLoader@0x00000007c0009c70

total = 353     12424   20369674            N/A         alive=1, dead=352           N/A    

说明:

  • class_loader:当 Java 虚拟机运行时,类加载器对象的地址
  • classes:已加载类的数量
  • bytes:该类加载器加载的所有类的元数据所占的字节数
  • parent_loader:父类加载器对象的地址,如果没有显示 null。
  • alive:是否存活的标识,表示类加载器对象是否将被垃圾回收。
  • type:该类加载器的类名。

将内存使用情况 dump 到文件

jmap -dump:format=b,file=dumpFileName <pid>

示例:

$ jmap -dump:format=b,file=/tmp/testdump.dat 37761
Dumping heap to /tmp/testdump.dat ...
Heap dump file created

通过 jhat 分析 dump 文件

jvm 的内存 dump 到文件中,这个文件是一个二进制的文件,不方便查看,可以借助于 jhat 工具进行查看。

jhat -port <port> <file>

示例:

$ jhat -port 8888 /tmp/testdump.dat
Reading from /tmp/testdump.dat...
Dump file created Thu Jul 07 17:10:28 CST 2022
Snapshot read, resolving...
Resolving 46403 objects...
Chasing references, expect 9 dots.........
Eliminating duplicate references.........
Snapshot resolved.
Started HTTP server on port 8888
Server is ready.

打开浏览器进行访问:ip + 端口(8888)即可访问。

OQL 查询

在最后面有 OQL 查询功能。

image-20220707171533990

示例:

select s from java.lang.String s where s.value.length >= 10000

image-20220707171442062