以自动方式查找泄漏内存的JUnit测试

时间:2009-05-14 15:15:00

标签: java unit-testing memory-leaks junit

我们问题的根源是单身人士。但单身人士很难打破,与此同时我们有很多单元测试使用单身人士而不用小心在tearDown()方法中完全清除它们。我认为检测这些测试的好方法是寻找内存泄漏。如果在tearDown()和System.gc()之后使用的内存大于测试开始时使用的内存,则测试泄漏或类加载器加载更多类。有没有办法自动检测这类问题?

6 个答案:

答案 0 :(得分:2)

您是否可以在TestCase和各个测试类之间引入一个子类来进行清理?那么子类只负责调用super.teardown() - 并且只负责那些有自己拆解()的人。

答案 1 :(得分:1)

我完全赞同监视内存使用情况的其他海报不是一种可行的方法来跟踪这一点 - System.gc()不会按照您的预期行事,或者具有足够的精确度来实现您的目标。

您将需要一个工具,可以让您检查参考图并显示分配调用堆栈。

我使用了来自Borland的OptimizeIt和来自ej-technologies的JProfiler,两者都取得了成功(快速谷歌显示OptimizeIt现在已经死了。)

还有可能使用JVMTI为这个特定问题组合一个更好的监视器。

编辑:很奇怪,但在我查看此答案时,我接到了Embarcadero的电话,他显然已经购买了OptimizeIt,进行了一些更新,现在正以{{3}的名义进行营销}。

答案 2 :(得分:0)

只是一个想法:如果你有两个空测试一个接一个地运行,第二个不应该在拆解()之后使用不同的内存。如果是这样,你(可能)在setup()/ teardown()系统的某个地方有泄漏。

答案 3 :(得分:0)

我认为这不是一个好方法。 System.gc()不能保证完全清理任何未使用的对象。

如果您的根本问题是您的单元测试最终使用全局数据(单例)而没有正确清理它们,您应该解决根本问题:这些单元测试。找到所有未使用tearDown()的测试或查找使用特定单例的所有测试应该不会太难。

答案 4 :(得分:0)

如果您的Singleton仅用于初始化一次,您可以使用代码检查重新初始化并在检测到时记录当前堆栈。然后,如果您检查堆栈,您将看到哪个测试得到了滚动,您可以检查JUnit日志以查看之前的测试运行情况。

在更彻底地解决这个问题方面,我建议你不要检测它,而是建议你有一个单例初始化程序来记住它初始化的内容,并且有一个拆卸方法可以删除它初始化的所有内容。这样,测试只能通过这个类进行初始化,而且只需要在拆解时做一件事。

我也认为Carl Manaster的建议很好,但是如果你使用的是JUnit4,那么你可以在超类中运行一个拆机方法,而不必记得打电话给super。除非您使用JUnit3 GUI,否则JUnit4应该是替代品。唯一的办法是利用它的新功能来迁移整个测试,你不能同时拥有同一个类。因此,与这些单例交互的测试必须一次迁移一个完整的测试类。

答案 5 :(得分:0)

您可以使用Eclipse Memory Analyzer自动分析每次测试后获取的堆转储,或者在所有测试之后可能更好。 MAT可以相当自动地发现内存泄漏。