从以上信息中可看出JVM堆的配置信息,如NewSize、NewRatio、SurvivorRatio等;JVM堆的使用情况,新生代中的Eden Space、From Space、To Space的使用情况,旧生代和持久代的使用情况。
要注意的是在使用CMS GC的情况下,jmap -heap的执行有可能会导致Java进程被挂起。
JVM中对象的内存的占用情况
在查看JVM内存状况时,除了要知道每个代的占用情况外,很多时候更要知道其中各个对象占用的内存大小,这样便于分析对象的内存占用情况,在分析OutOfMemory的场景中尤其适用。
输入jmap -histo [pid]即可查看jvm堆中对象的详细占用情况,如图1所示。
图1 jmap -histo运行效果
输出内容按照占用空间的大小排序,例如上面的[C,表示char类型的对象在jvm中总共有243 707个实例,占用了501 638 784 bytes的空间。
导出整个JVM中的内存信息
通过以上方法能查看到JVM中对象内存的占用情况,但很多时候还要知道这个对象到底是谁创建的。例如上面显示出来的[C,只知道它占用了那么多的空间,但不知道是什么对象创建出的[C,于是jmap提供了导出整个jvm中的内存信息的支持。基于一些jvm内存的分析工具,例如sun JDK 6中的jhat、Eclipse Memory Analyzer,可以分析jvm中内存的详细信息,例如[C是哪些对象创建的。
执行如下命令即可导出整个jvm中的内存信息:
jmap -dump:format=b,file=文件名 [pid] |
5. JHat
JHat是Sun JDK 6及以上版本中自带的一个用于分析jvm堆dump文件的工具,基于此工具可分析jvm heap中对象的内存占用状况、引用关系等。
执行如下命令分析jvm堆的dump文件:
jhat -J-Xmx1024M [file] |
执行后等待console中输出Started HTTP server on port 7000,看到后就可以通过浏览器访问http://ip:7000了,此页面默认为按package分类显示系统中所有的对象实例。在页面的最下端有Other Queries导航,其中有显示jvm中对象实例个数的链接、有显示jvm中对象大小的链接等,点击显示jvm中对象大小的链接,得到的结果如图2所示。
图2 jhat运行效果
点击图2中的class [C,可以看到有哪些对象实例引用了这个对象,或者创建了这个对象,jhat在分析大的堆dump文件时表现不好,速度很慢。