到新公司也快两个月了,感叹下庞大的业务量提升带来许多以前不会去遇到并探索的问题。这里先分析下java堆内内存。
当应用内老年代占比逐渐涨到比较高而且不太能被回收时,这个时候就要注意了是否是内存泄露。 关于如何观察内存,可以jmap -heap 抑或 jstat -gcutil 1000 10。 当然最直观的用jconsole连上去一瞅便知。当然了应用的启动参数里加上

-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9987 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=192.168.1.1

如果Old Gen 使用过高,这里 可以通过指令jmap -dump:format=b,file=test.bin 把内存dump下来,然后存到本地来进行分析
这里建议windows的同学使用IBM的Eclipse Memory Analyzer 工具。可以直接下载该工具(建议MAT64位)或者eclipse插件。
这里介绍下插件安装
Help -> Install new Software -> 根据不同的eclipse版本选择,如我得Juno版本选择 Work with: Juno - http://download.eclipse.org/releases/juno -> General Purpose Tools -> 勾选 Memory Analyzer 和 Memory Analyzer(Charts) ->确定后完成安装,自动重启Eclipse后生效。
这里介绍下mat的使用(http://www.ibm.com/developerworks/cn/opensource/os-cn-ecl-ma/index.html ibm的这个简介可以先看下)
open file 后打开刚才生成的 test.bin 文件 ,选择leak分析。基本上列出的一些信息可以感觉到一些内存泄露的点(如果有)
要是没问题,分析一年 都分析不出来,所以可以试着用jconsole里面点点gc看看是否能回收。
另外可以看到 Dominator Tree,这边会列出一些使用比较大的对象,依次点进去看看这些大的对象最后是被哪些gc root索引到了。一般会是map,list这种对象里面保存了大量无用的引用导致的
或者看Histogram,ShallowHeap排序(这个指当前对象占用的大小)RetainedHeap指一直累积所属下面的对象 大小。右键List Objects ->with incoming refs 。再根据shallow排序后,分别右键前面几个 Path to GC Roots -> exclude all xxx refs。看到这些大的内存使用空间未被释放的原因。和Dominator Tree 其实差不多一样的意思。
另外如果堆内内存使用比较多,会放在服务器上分析比较妥善。分析完拿所有的零碎文件在本地打开即可。
另外的另外如果是MAT工具,可以修改 文件夹下.ini文件 配置-Xmx=4g,这样工具不会爆出oom(不然内存会不够用噢)

« JVM 崩溃分析 Java并发编程:Callable、Future和FutureTask »