JVM 内存分析工具笔记

jmap 命令

1. 获取heap dump文件

jmap -dump:live,format=b,file=h.hprof [pid] # 会触发gc,只转存存活对象

或者

jmap -dump:format=b,file=h3.hprof [pid]

jmap的作用并不仅仅是为了获取堆转储快照,它还可以查询finalize执行队列、Java堆和方法区的详细信息,如空间使用率、当前用的是哪种收集器等。

jmap工具的主要选项如下:

选项描述
-dump用于生成JVM的heap快照文件,命令格式:jmap -dump[:live],format=b,file=<filename.prof> <pid>,其中live可选,表示是否只导出存活对象,如果指定会触发GC。
-finalizernfo该命令只能在类Unix环境下运行,用于显示在F-Queue中等待Finalizer线程执行finalize方法的对象。
-heap该命令只能在类Unix环境下运行,用于显示当前Java heap的详细信息,例如使用那种回收器,详细的参数,分代情况等。
-histo显示堆中对象统计信息,包括对象示例、类、合计容量信息。
-F当JVM对-dump不响应时可以使用该参数强制生成heap dump快照文件。

如下是在mac中执行–help命令的帮助文档

jdk8

$ jmap --help
Usage:
    jmap [option] <pid>
        (to connect to running process)
    jmap [option] <executable <core>
        (to connect to a core file)
    jmap [option] [server_id@]<remote server IP or hostname>
        (to connect to remote debug server)

where <option> is one of:
    <none>               to print same info as Solaris pmap
    -heap                to print java heap summary
    -histo[:live]        to print histogram of java object heap; if the "live"
                         suboption is specified, only count live objects
    -clstats             to print class loader statistics
    -finalizerinfo       to print information on objects awaiting finalization
    -dump:<dump-options> to dump java heap in hprof binary format
                         dump-options:
                           live         dump only live objects; if not specified,
                                        all objects in the heap are dumped.
                           format=b     binary format
                           file=<file>  dump heap to <file>
                         Example: jmap -dump:live,format=b,file=heap.bin <pid>
    -F                   force. Use with -dump:<dump-options> <pid> or -histo
                         to force a heap dump or histogram when <pid> does not
                         respond. The "live" suboption is not supported
                         in this mode.
    -h | -help           to print this help message
    -J<flag>             to pass <flag> directly to the runtime system

jdk11

$ jmap --help
Usage:
    jmap -clstats <pid>
        to connect to running process and print class loader statistics
    jmap -finalizerinfo <pid>
        to connect to running process and print information on objects awaiting finalization
    jmap -histo[:live] <pid>
        to connect to running process and print histogram of java object heap
        if the "live" suboption is specified, only count live objects
    jmap -dump:<dump-options> <pid>
        to connect to running process and dump java heap
    jmap -? -h --help
        to print this help message

    dump-options:
      live         dump only live objects; if not specified,
                   all objects in the heap are dumped.
      format=b     binary format
      file=<file>  dump heap to <file>

    Example: jmap -dump:live,format=b,file=heap.bin <pid>

2. jmap -heap

如果需要在jdk11中查看类似在jdk8中的jmap -heap <pid>的内容,需要执行jhsdb jmap --heap --pid <pid>

执行如下:

$ jhsdb jmap --heap --pid 10950
Attaching to process ID 10950, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 11.0.12+8-LTS-237

using thread-local object allocation.
Garbage-First (G1) GC with 8 thread(s)

Heap Configuration:
   MinHeapFreeRatio         = 40
   MaxHeapFreeRatio         = 70
   MaxHeapSize              = 134217728 (128.0MB)
   NewSize                  = 1363144 (1.2999954223632812MB)
   MaxNewSize               = 79691776 (76.0MB)
   OldSize                  = 5452592 (5.1999969482421875MB)
   NewRatio                 = 2
   SurvivorRatio            = 8
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB
   G1HeapRegionSize         = 1048576 (1.0MB)

Heap Usage:
G1 Heap:
   regions  = 128
   capacity = 134217728 (128.0MB)
   used     = 100663296 (96.0MB)
   free     = 33554432 (32.0MB)
   75.0% used
G1 Young Generation:
Eden Space:
   regions  = 14
   capacity = 22020096 (21.0MB)
   used     = 14680064 (14.0MB)
   free     = 7340032 (7.0MB)
   66.66666666666667% used
Survivor Space:
   regions  = 4
   capacity = 4194304 (4.0MB)
   used     = 4194304 (4.0MB)
   free     = 0 (0.0MB)
   100.0% used
G1 Old Generation:
   regions  = 78
   capacity = 108003328 (103.0MB)
   used     = 81788928 (78.0MB)
   free     = 26214400 (25.0MB)
   75.72815533980582% used

3. jmap -histo

使用jmap -histo <pid>可以统计出当前JVM进程中的对象量,如下:

$ jmap -histo 10950
 num     #instances         #bytes  class name (module)
-------------------------------------------------------
   1:       1127420       38934176  [B (java.base@11.0.12)
   2:       1007019       24168456  java.lang.String (java.base@11.0.12)
   3:       1000660       24015840  java.util.LinkedList$Node (java.base@11.0.12)
   4:        119709        5746032  java.nio.HeapCharBuffer (java.base@11.0.12)
   5:           521        1449296  [I (java.base@11.0.12)
   6:         59856        1436544  java.lang.StringBuilder (java.base@11.0.12)
   7:          1050         128360  java.lang.Class (java.base@11.0.12)
   8:          3163         101216  java.util.HashMap$Node (java.base@11.0.12)
   9:           884          87152  [Ljava.lang.Object; (java.base@11.0.12)
  10:           387          55208  [Ljava.util.HashMap$Node; (java.base@11.0.12)
  11:            12          50104  [C (java.base@11.0.12)
  12:          1156          46240  java.util.LinkedHashMap$Entry (java.base@11.0.12)
  13:          1177          37664  java.util.concurrent.ConcurrentHashMap$Node (java.base@11.0.12)
  ...

jhat 命令

在使用jmap或者其他方式,获取到java heap的dump文件之后,对文件内容进行分析

jhat是一个用来分析java的堆情况的命令。jhat命令将dump文件转成html的形式,然后通过http访问可以查看堆情况。

jdk11查看帮助文档:

$ jhat -h
Usage:  jhat [-stack <bool>] [-refs <bool>] [-port <port>] [-baseline <file>] [-debug <int>] [-version] [-h|-help] <file>

	-J<flag>          Pass <flag> directly to the runtime system. For
			  example, -J-mx512m to use a maximum heap size of 512MB
	-stack false:     Turn off tracking object allocation call stack.
	-refs false:      Turn off tracking of references to objects
	-port <port>:     Set the port for the HTTP server.  Defaults to 7000
	-exclude <file>:  Specify a file that lists data members that should
			  be excluded from the reachableFrom query.
	-baseline <file>: Specify a baseline object dump.  Objects in
			  both heap dumps with the same ID and same class will
			  be marked as not being "new".
	-debug <int>:     Set debug level.
			    0:  No debug output
			    1:  Debug hprof file parsing
			    2:  Debug hprof file parsing, no server
	-version          Report version number
	-h|-help          Print this help and exit
	<file>            The file to read

For a dump file that contains multiple heap dumps,
you may specify which dump in the file
by appending "#<number>" to the file name, i.e. "foo.hprof#3".

All boolean options default to "true"
选项描述
-stack false|true关闭对象分配调用栈跟踪(tracking object allocation call stack)。 如果分配位置信息在堆转储中不可用. 则必须将此标志设置为 false. 默认值为 true.
-refs false|true关闭对象引用跟踪(tracking of references to objects)。 默认值为 true. 默认情况下, 返回的指针是指向其他特定对象的对象,如反向链接或输入引用(referrers or incoming references), 会统计/计算堆中的所有对象。
-port port-number设置 jhat HTTP server 的端口号. 默认值 7000.
-exclude exclude-file指定对象查询时需要排除的数据成员列表文件(a file that lists data members that should be excluded from the reachable objects query)。 例如, 如果文件列列出了 java.lang.String.value , 那么当从某个特定对象 Object o 计算可达的对象列表时, 引用路径涉及 java.lang.String.value 的都会被排除。
-baseline exclude-file指定一个基准堆转储(baseline heap dump)。 在两个 heap dumps 中有相同 object ID 的对象会被标记为不是新的(marked as not being new). 其他对象被标记为新的(new). 在比较两个不同的堆转储时很有用.
-debug int设置 debug 级别. 0 表示不输出调试信息。 值越大则表示输出更详细的 debug 信息.
-version启动后只显示版本信息就退出
-J< flag >因为 jhat 命令实际上会启动一个JVM来执行, 通过 -J 可以在启动JVM时传入一些启动参数. 例如, -J-Xmx512m 则指定运行 jhat 的Java虚拟机使用的最大堆内存为 512 MB. 如果需要使用多个JVM启动参数,则传入多个 -Jxxxxxx.

运行命令jhap <dump_file>:

$ jhat java_pid10301.hprof
Reading from Desktop/java_pid10301.hprof...
Dump file created Sat Dec 18 10:47:28 CST 2021
Snapshot read, resolving...
Resolving 4830119 objects...
Chasing references, expect 966 dots.................
Eliminating duplicate references................
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.

然后使用浏览器访问本地7000端口:

在这里插入图片描述

页面功能简介

一般查看堆异常情况主要看这个两个部分:

1、Show instance counts for all classes (excluding platform),平台外的所有对象信息。

2、Show heap histogram 以树状图形式展示堆情况。

具体排查时需要结合代码,观察是否大量应该被回收的对象在一直被引用或者是否有占用内存特别大的对象无法被回收。

OQL

jhat还提供了一种对象查询语言(Object Query Language),OQL有点类似SQL,可以用来查询。

OQL语句的执行页面: http://localhost:7000/oql/

OQL帮助信息页面为: http://localhost:7000/oqlhelp/

mat 工具

下载地址Memory Analysis Tool

安装忽略

MAT进行OOM分析,多点点就清楚了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值