Java的内存映像工具,jmap,Memory Map for Java,用于生成堆转储快照,一般成为heapdump或者dump文件,出了获取dump文件,这个工具还可以查询finalize执行队列,Java堆和永久代的详细信息,如空间使用率、当前使用的是哪种收集器等。
先来看一下这个命令是怎么用的:
由此可见jmap的命令格式为:jmap [option]
option参数为:
no option: 查看进程的内存映像信息,类似 Solaris pmap 命令。heap: 显示Java堆详细信息histo[:live]: 显示堆中对象的统计信息clstats:打印类加载器信息finalizerinfo: 显示在F-Queue队列等待Finalizer线程执行finalizer方法的对象dump::生成堆转储快照F: 当-dump没有响应时,使用-dump或者-histo参数. 在这个模式下,live子参数无效.help:打印帮助信息J:指定传递给运行jmap的JVM的参数
1、jmap -heap pid,显示Java堆详细信息,包括使用的GC算法、堆配置信息和各内存区域内存使用信息
2、jmap -histo:live pid,显示堆中对象的统计信息,如果指定了live子选项,则只计算活动的对象。
打印的统计信息如下(包括每个Java类、对象数量、内存大小(单位:字节)、完全限定的类名):
3、jmap -clstats pid,打印类加载器信息
-clstats是-permstat的替代方案,在JDK8之前,-permstat用来打印类加载器的数据,打印Java堆内存的永久保存区域的类加载器的智能统计信息。
4、jmap -finalizerinfo pid,打印等待终结的对象信息
5、jmap -dump: pid,生成堆转储快照dump文件
以hprof二进制格式转储Java堆到指定filename的文件中。live子选项是可选的。如果指定了live子选项,堆中只有活动的对象会被转储。想要浏览heap dump,你可以使用jhat(Java堆分析工具)读取生成的文件,我们先来生成这个文件:
生成了这个堆转储快照,接下来就到了jhat命令行工具的使用了,jhat是虚拟机堆转储快照分析工具,该命令与jmap配合使用,来分析jmap生成的堆转储快照,是对好基友。jhat内置了一个微型的HTTP/HTML服务器,生成dump文件的分析结果后,可以在浏览器中查看。
注意:一般在生成环境中,不使用jhat命令行工具在部署服务器上直接来分析堆转储快照,因为分析堆转储快照是一个耗时且消耗硬件资源的过程,还有就是jhat的分析功能相对来说比较简陋,有比jhat更为先进的工具,例如EMA,IBM HA等,都是更强大更专业的分析功能。
先来看一下它的使用方法:
这些可选择的选项含义是:
-J 将运行时参数传递给运行jhat的JVM。例如,-J-Xmx512m设置使用的最大堆内存大小为512MB。-stack false/true关闭跟踪对象分配调用堆栈。注意,如果heap dump中的分配位置信息不可用,你必须设置此标识为false。此选项的默认值为true。-refs false/true关闭对象的引用跟踪。默认为true。默认情况下,反向指针(指向给定对象的对象,又叫做引用或外部引用)用于计算堆中的所有对象.-port port-number设置jhat的HTTP服务器的端口号。默认为7000。-exclude exclude-file指定一个数据成员列表的文件,这些数据成员将被排除在”reachable objects”查询的范围之外。举个例子,如果文件列有java.lang.String.value,那么,当计算指定对象”o”的可达对象列表时,涉及到java.lang.String.value字段的引用路径将会被忽略掉。-baseline baseline-dump-file指定一个基线heap dump。在两个heap dump(当前heap dump和基线heap dump)中存在相同对象ID的对象,不会被标记为”new”。其他的对象将被标记为”new”。这在比较两个不同的heap dump时非常有用。-debug int设置此工具的调试级别。0意味着没有调试输出。设置的值越高,输出的信息就越详细。-version 报告版本号并退出。-h|-help输出帮助信息并退出。
输入命令来分析刚才生成的堆转储文件:
打开浏览器来访问,端口为默认的7000:
在这个页面的最下方,有个Other Queries,点击不同的链接可以展示不同的内容:
比如我们点击“Show heap histogram” 链接,展示堆快照直方图:
这些JDK自带的工具,给予我们分析和排查问题带来了极大的方便,掌握这些工具,或者其他更强大和更完美的工具,让我们分析线上问题的时候,不再手足无措。