Eclipse的Mat Plugin查找OOM使用一例
最近接手了一个老项目比较头痛。头痛的原因是这个代码的编写者已经离开了公司,而且代码基本没有注释,结构混乱并且还有严重的内存泄漏问题。其实接手这个项目最大需要解决的问题就是内存泄漏问题。由于这个老项目使用JDK1.5,所以像JDK1.6自带很多内存检测工具都派不上用场了。比如:jdk1.5 使用的jmap -heap 生成的dump文件用eclipse的mat就打不开。jdk1.5的jstat 不能看到live的对象。这就使查错的难度增加了不少。不过还好,通过更改测试服务器(read hat 5.0)上环境变量后,可以使用jmap -F -dump:format=b,file=dump.bin <pid> 来生成dump文件方便分析。所以如下就是分析内存泄漏的一个流程:
1.用jdk自带工具jmap追踪jvm的dump信息。见图
2.mat工具进行分析。如图
3.分析占用内存最多的类->方法->调用对象。如图
4.具体找到哪个对象占用内存较多。如图
5.OK,现在明了了,那么可以去找对应java代码了。如图
总结:
VelocityContext可能会导致内存泄漏(实际上是聚集了太多的内省信息)。原因是VelocityContext会堆积它所访问过的每个模板的内省信息,如果template缓存被关闭,将导致VelocityContext每次都访问一个新的模板,从而堆积更多的内省信息。
强烈建议做如下的事情:
·当template处理结束后创建一个新的VelocityContext,这将阻止堆积内省信息。如果你需要重用携带数据和对象的VelocityContext,可以简单的用另一个VelocityContext来包装它。外层的VelocityContext将会堆积内省的信息,但另人兴奋的是你将丢弃它!
·开启模板的缓存机制!这将阻止每次都对template重新解析,这样VelocityContext不仅可以避免增加内省信息,同时还可以改进程序。
·在循环迭代期间重用Template对象。这样,当缓存关闭的时候就不用强迫Velocity一次又一次的去重新读取和重新解析同样的template,因此,VelocityContext也就不会每次都堆积新的内省信息!