讨论一下Java应用内存泄露探测工具的实现思路

jlusdy 2012-10-30
最近有个想法,看看能不能实现一个Java应用内存泄露探测工具,大致思路是在运行态用javaagent和instrumentation机制替换class,记录对象的创建,然后用弱引用识别对象是否被回收,最后汇总数据识别哪个对象属于内存泄露(简单一点,只需要识别出哪个class就行,上下文 调用栈 参数等都不记录,只记录对象创建次数和大小,不然工具本身占用资源太多)

rednaxelafx大神和群友一起来讨论下这个思路可行否

PS. iPad上发的帖,简单了点,勿怪
RednaxelaFX 2012-10-31
刚才在那边想跟你说的是:
·首先应该识别并定义你要解决的问题
·然后看这个问题需要怎样的信息
·然后才是如何去收集这些信息
(如果分析某问题已有某些现成的手段,那新的手段与现有的有何异同,优劣点在什么地方也应该仔细分析)

所以能拜托叔同补充一下背景信息不?

如果要非常高精度的确认某个对象“是谁”,那就需要记录非常多的信息,例如创建时的调用栈、创建时的参数以及某些环境信息等。
不记录这些就无法精确判断对象的“身份”,到头来得到的信息跟按固定间隔/按某些特定事件来做heap dump来收集数据并且做分析能做到的差别并不大。

叔同你想这个方法的初衷是不是想尽量避免在大堆上做周期性heap dump,但又想获取跟做了heap dump类似的分析能力?

P.S. 顺带放个链接,以前我做的笔记,关于NetBeans Memory Profiler的。http://book.douban.com/annotation/15120953/
这个你应该读过了,不过可能有别人也对这个话题感兴趣的。放这儿增加点背景资料

可以看到NetBeans Memory Profiler就是用instrumentation记录了对象的创建,以此为依据来统计对象的年龄分布状况。

不过它并不需要用弱引用,在创建点记录的信息并不直接用来跟踪单个单个的对象。后面还是周期性向JVM请求histogram来做统计的。
jlusdy 2012-10-31
RednaxelaFX 写道

·首先应该识别并定义你要解决的问题
·然后看这个问题需要怎样的信息
·然后才是如何去收集这些信息
(如果分析某问题已有某些现成的手段,那新的手段与现有的有何异同,优劣点在什么地方也应该仔细分析)

所以能拜托叔同补充一下背景信息不?
...................
叔同你想这个方法的初衷是不是想尽量避免在大堆上做周期性heap dump,但又想获取跟做了heap dump类似的分析能力?

我最开始没有讲清楚,初衷是想实现一个用法简单 部署方便 资源消耗少 主动探测的工具。
使用场景是怀疑应用有内存泄露就部署上去运行一段时间,工具就把结论输出出来;
为了能快速解决问题,当然是记录下的信息全面点好,最起码应该有调用栈 和 参数;
现有的这些方式方法都各有弊端而且门槛较高(比如周期性heap dump)。

这种工具貌似堆内对象探测可以实现,堆外内存就探测不了了

看起来NetBeans Memory Profiler的实现更简单一点
RednaxelaFX 2012-10-31
都要对创建对象来做instrumentation了这开销本来就小不到哪里去,特别是对分配频繁的应用来说。
而且你原本想的弱引用跟踪所以新建对象的做法会极大的增加GC堆的压力,不信你可以实际试试,反正这个概念要实现原型出来很容易。

我不太喜欢这个方案,所以想退一步看你真正要解决的问题是什么。
如果还要连unmanaged那边也监视上的话那自然是不能指望用纯Java的解决方案咯。但先把managed heap监控好就好了,不必大而全
jlusdy 2012-10-31
好的
我周末写一个demo,验证下对GC的压力有多大,在不在可以接受的范围内

另外,解决此类问题,包括堆内和堆外 R大有没有什么好的资料可以分享?
Global site tag (gtag.js) - Google Analytics