您的位置:首页 > 编程语言 > Java开发

记一次内存泄漏排查问题

2017-02-26 21:51 393 查看
原文链接: 链接

背景

在使用JavaCV做图像处理时,发现程序运行起来之后,处理了百来次的时候,就报了outofmemory的错误。因为javacv底层就是调用opencv的native方法,判断是出现了内存泄漏问题,可能是调用了哪个方法之后没有正确释放资源。

1.用jconsole观察

首先是需要在测试机器上修改启动命令,使得能够支持jconsole远程连接。

-Dcom.sun.management.jmxremote.port=8999 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false


这样,启动本地java安装目录bin下的jconsole.exe启动界面,输入远程主机的IP和8999端口,就可以连接上了。



这个图是正常的垃圾回收。当时的图是只有上升,没有下降的一个过程,然后到顶点就产生了outofmemory错误。

2.排查

网上查询了一下内存泄漏的分析工具,给eclipse安装了MAT插件用于分析文件。为了生成hprof文件,在测试机器上多次调用方法,直到根据jconsole发现快到顶点了,运行以下命令:

jmap -dump:format=b,file=a.hprof  24957
//后面的24957是进程ID可用下面命令get
ps -ef|grep java
然后找到项目名对应的pid即可


生成的文件直接用装了MAT插件的eclipse打开即可:



可以看到图中很明显的第三方库的类名,就可以判断可能是在用该类的地方的资源没释放,然后对应地查找。当然MAT和jconsole还有更强大的功能等着大家去使用

Objects : 类的对象的数量,这个对象被创建了多少个

shallowHeap是指一个对象内存的消耗大小,不包含对其他对象的引用。

Retained Heap :是shallow Heap的总和,也就是该对象被GC之后所能回收到内存的总和。

该篇博客中具体介绍了shallowheap和retainedHeap:

http://bjyzxxds.iteye.com/blog/1532937

这里说一句题外话,在使用这几个类的地方,发现用完之后已经调用了释放方法,很是奇怪,也没头绪。后面想到跟javacv给的sample code对比一下,发现网上流传的释放方法和样例中的并不一致,也可能是因为使用的版本不同导致的。改成样例中的方法之后,解决了该问题。得到的教训是如果第三方库有示例代码,还是得多参考示例代码。

最终再用jconsole连接机器,观察内存回收,就得到了上面那个图。还有下面这个图:



这里看到使用的回收算法是新生代是parNew,老年代是CMS。老年代算法中,CMS算是用的较多的算法,而新生代算法中,除了serial收集器,只有parNew能与CMS配合使用。parNew与serial相比,只是多线程,没有其他创新之处。顺势复习了一波垃圾回收算法,做了下面这样一个几种收集算法对比:

链接:https://www.processon.com/view/587a409de4b098bf4ca43bf7
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Javacv jvm 内存泄漏