所以,我有了这个想法,写一些代码可以自动检测并指出测试中潜在的内存泄漏,我只是想看看我的想法是否合理,然后再去实现它。
本质上,内存泄漏被定义为越来越多的未使用引用。在 Java 中,与 C++ 相比,这种危险显着降低,因为我们没有悬空指针或忘记 delete() 等危险。
所以这限制了我们在 Java 中发生内存泄漏的方式。我们可以有一个对象的静态引用,或者我们可以在当前运行的线程中有本地引用,就是这样,对吧?
我的想法是编写一个例程,查看所有已知的项目类文件,并提取所有静态引用。然后需要向下“递归”引用,并且需要向上计数它所具有的所有实例引用。对象引用占用一定数量的内存,而基元占用一定数量的内存,我们可以统计所有这些。您可以触发该例程一次,以获得基线,然后执行您认为会导致内存泄漏的事情,然后再次运行该例程并比较结果。可以设置一个增量阈值,然后您可以手动确定哪些对象有目的地变大,哪些对象变大了,但不应该有。
当然,这是一个测试工具,但是,在我从事的项目中,通常我只能在生产中重现这些错误,有很多用户,所以使用真正的分析器并不总是一种选择。内置此功能可以避免实际运行分析器,并且在大多数情况下都可以正常运行,除非在生产产品上诊断问题时。
我看到的唯一问题是,当前正在运行的线程中的局部变量无法以这种方式访问,但是,知道这一限制,可能需要代码将这些本地(但长期引用)注册到测试类本身,这将在静态变量中保存对这些对象的弱引用,从而允许对引用进行计数。
垃圾收集将是一个问题,所以基本上,我会通过创建一个未引用的对象来“强制”垃圾收集,它会覆盖 finalize 以在收集它时通知我的线程,这将导致我的 GC 检测器停止阻塞,然后运行检漏仪。
所以,我的问题是,这听起来合理吗?你认为这会产生有用的结果吗?