原来jdk自带了这么好玩的工具 > jmap 使用教程

您所在的位置:网站首页 怎么打开jdk使用方法教程视频 原来jdk自带了这么好玩的工具 > jmap 使用教程

原来jdk自带了这么好玩的工具 > jmap 使用教程

2024-07-11 17:12| 来源: 网络整理| 查看: 265

前言

本次博客测试环境使用的是JDK1.8,系统使用CentOS Linux release 7.4.1708 (Core)

什么是jmap

jmap是一个多功能的命令,也是jdk自带的命令,是我们在开发过程中用来虚拟机性能能分析和故障解决必不可少的工具之一,它可以生产java程序的堆栈(dump)文件;也可以查看堆内的对象信息、Classloader 类加载信息以及finalizer队列(java将要回收的垃圾队列);另外,jmap没有图形界面,所有的操作都是在命令行完成的。

使用方法 命令格式: jmap [options] options参数命令详解 no option:不带参数查询进程,就像这样jmap 12271,查看内存中共享对象信息;,类似Solaris pmap命令;heap: 显示java堆详细信息histo[:live] :显示堆中对象的统计信息,加:live值打印存活的对象,如果不加:live则查询所有的对象;clstats:打印类加载信息finalizerinfo:显示在F-Queue队列等待被清理的对象;在发生GC之前某些对象可能要被回收,那么在回收之前,这些对象就会放到F-Queue队列中;清理时会执行对象的finalizer()方法;dump :生成堆转储快照;

在测试每个参数之前,我们先用jps命令看看linux系统中有哪些java进程 在这里插入图片描述 太好了,有一个可以用的,这是我自己线上的项目,进程为12771,等下就拿这个进程来测试;

no option 无参数查进程–查看内存中共享对象信息 jmap 12771

通过结果可以看到:

第一列打印的16进制是每个共享对象的其实地址第二列是对象的映射大小第三列是共享对象文件的路径全称

只是对于我们开发人员来说,这些信息对我们没有多大作用,所以了解一下即可,没必要深究。 在这里插入图片描述

1、 -heap 显示java堆详细信息 jmap -heap 12771

打印结果如下

[root@VM_0_5_centos ~]# jmap -heap 12771 Attaching to process ID 12771, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.232-b09 using thread-local object allocation. Mark Sweep Compact GC Heap Configuration: MinHeapFreeRatio = 40 MaxHeapFreeRatio = 70 MaxHeapSize = 482344960 (460.0MB) NewSize = 10485760 (10.0MB) MaxNewSize = 160759808 (153.3125MB) OldSize = 20971520 (20.0MB) NewRatio = 2 SurvivorRatio = 8 MetaspaceSize = 21807104 (20.796875MB) CompressedClassSpaceSize = 1073741824 (1024.0MB) MaxMetaspaceSize = 17592186044415 MB G1HeapRegionSize = 0 (0.0MB) Heap Usage: New Generation (Eden + 1 Survivor Space): capacity = 22413312 (21.375MB) used = 14306760 (13.643989562988281MB) free = 8106552 (7.731010437011719MB) 63.83153011924342% used Eden Space: capacity = 19988480 (19.0625MB) used = 12015896 (11.459251403808594MB) free = 7972584 (7.603248596191406MB) 60.11410572489754% used From Space: capacity = 2424832 (2.3125MB) used = 2290864 (2.1847381591796875MB) free = 133968 (0.1277618408203125MB) 94.47516364020271% used To Space: capacity = 2424832 (2.3125MB) used = 0 (0.0MB) free = 2424832 (2.3125MB) 0.0% used tenured generation: capacity = 49614848 (47.31640625MB) used = 33554184 (31.99976348876953MB) free = 16060664 (15.316642761230469MB) 67.62931935214233% used 25942 interned Strings occupying 2999576 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 空间的大小。

Heap Usage: New Generation (Eden + 1 Survivor Space): capacity = 22413312 (21.375MB) used = 14306760 (13.643989562988281MB) free = 8106552 (7.731010437011719MB) 63.83153011924342% used

新生代内存使用情况(伊甸区 + 1个Survivor区(S0区或S1区))

capacity (容量):一共有21.375M used:已使用13.6M free:剩余7.7M use(使用率):63.83%

Eden Space::伊甸区使用情况 From Space: :from区 (Survivor区)使用情况 To Space::to区(Survivor区)使用情况 tenured generation: :老年代使用情况

2、-histo[:live] 显示堆中对象的统计信息(到目前为止还存活的对象) jmap -histo:live 12771

打印结果如下,默认会以占用的大小倒序排列;

[root@VM_0_5_centos ~]# jmap -histo 12771 num #instances #bytes class name ---------------------------------------------- 1: 86764 11326648 [C 2: 3817 4359520 [B 3: 6008 2580208 [I 4: 24207 2130216 java.lang.reflect.Method 5: 79367 1904808 java.lang.String 6: 12306 1374208 java.lang.Class 7: 39215 1254880 java.util.concurrent.ConcurrentHashMap$Node 8: 12569 777336 [Ljava.lang.Object; 9: 17820 570240 java.util.HashMap$Node 10: 14160 566400 java.util.LinkedHashMap$Entry 11: 6512 550864 [Ljava.util.HashMap$Node; 12: 27815 445040 java.lang.Object 13: 20176 444472 [Ljava.lang.Class; 14: 7789 436184 java.util.LinkedHashMap 15: 5890 424080 java.lang.reflect.Field 16: 197 391320 [Ljava.util.concurrent.ConcurrentHashMap$Node;

如果我们想要打印占用空前最多的前5个对象,可以这么写:

[root@VM_0_5_centos ~]# jmap -histo:live 12771 | head -8 num #instances #bytes class name ---------------------------------------------- 1: 95096 12216648 [C 2: 93199 2236776 java.lang.String 3: 5575 1618464 [B 4: 13052 1459872 java.lang.Class 5: 5824 1457256 [I

其中,head -8表示打印结果的从头8行的内容,因为表头和横线还需要占一些空间;所以最终显示的就是有5行内容

结果说明

num: 第一列为行号 instances: 第二列为对象的实例数量 bytes: 第三列为对象占用总大小,单位:字节 class name: 第四列为类的全局限定名,这里需要注意,[C表示char[]数组,[B表示byte[]数组,[I表示int[]数组

3、-clstats 打印类加载信息 jmap -clstats 12771

输入这个命令后需要等一会,我的linux配置比较低,等了一分钟才出来结果;所以这边使用windows系统来执行命令,结果如下 在这里插入图片描述

4、-finalizerinfo 显示在F-Queue队列等待被清理的对象 jmap -finalizerinfo 12771

打印结果如下,可以看到最后一行显示为0,表示当前队列中没有被清理的对象;这是因为垃圾清理过程的速度非常快,是毫秒级别的,所以大部分时间,这个队列里都是没有对象的,

[root@VM_0_5_centos ~]# jmap -finalizerinfo 12771 Attaching to process ID 12771, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.232-b09 Number of objects pending for finalization: 0 5、-dump 生成堆转储快照 jmap -dump:live,format=b,file=jmap.bin 12771

在执行之前,先说明下这个命令的参数

:live: 只打印存活的对象 format=b:以二进制的格式进行存储 file=jmap.bin:将文件保存到当前目录,文件名称为jmap.bin

打印结果如下

[root@VM_0_5_centos ~]# jmap -dump:live,format=b,file=jmap.bin 12771 Dumping heap to /root/jmap.bin ... Heap dump file created

这时候堆转储快照就已经生成了,二进制文件已经保存到目录:heap to /root/jmap.bin了。 在这里插入图片描述 因为是二进制文件,所以这里面的信息直接看是看不到的 在这里插入图片描述 这个堆转储文件需要用jhat命令或者jvisualvm 打开,jvisualvm 是图形界面,观看更加直观些,jhat这个工具因为使用起来会启动内置的Http的服务器,生成的结果可在浏览器中观看,但是jhat这个工具现在已经很少使用了,主要原因有2个

1是这个功能比较简陋,因为有了其他更强大的工具来分析,比如jvisualvm2是一般不会在部署了应用程序的服务器上直接分析dump文件,就算要分析,也会拷贝到其他机器上进行分析,因为分析工作既耗时又耗硬件资源;除非逼不得已,不然不会这么做;

使用jhat打开,命令如下,启动后就会启动内置的服务器,默认端口号:7000;启动后直接在浏览器访问:localhost:7000即可

jhat jmap.bin

在这里插入图片描述

其实jmap是一个不可替代的工具,至少当现在为止还没有出现替代的工具,在线上项目调优时,使用jmap -histo:live pid命令会比较方便查看内存泄漏的原因,阿里巴巴的arthas工具目前也还没有jmap的histo功能;这就是它不可替换的原因;



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3