我有一个可能分配大量数据的java类。
我已经编写了一个junit测试,应该检查内存泄漏,类似于下面的代码。
不幸的是,测试失败了。
@Test
public void shoudNotMemoryLeak()
{
Runtime runtime = Runtime.getRuntime();
// make shure that gc has collected all
System.gc ();
System.runFinalization ();
// memory before creating my sut
long memoryUsedBefore = runtime.freeMemory();
long memoryUsedAfter = 0;
// this consumes memory
StringBuilder sut = new StringBuilder("hello world");
// make memory available to gc
sut = null;
// make shure that gc has collected all
System.gc ();
System.runFinalization ();
// memory after creating my sut
memoryUsedAfter = runtime.freeMemory();
// this fails
assertEquals(memoryUsedAfter, memoryUsedBefore);
}
如何修改junittest以检查内存泄漏?
[更新]
不幸的是,9岁的可能重复没有提供我的问题我更改了标题和内容,使其比“可能的重复候选人”
更具体答案 0 :(得分:3)
使用单元测试测试内存泄漏时会出现几个问题;
首先,在Javadoc中,运行System.gc()
和System.runFinalization()
似乎并不能保证收集和最终确定的发生,因为它提到“尽力而为”
调用gc方法表明Java虚拟机花费了大量精力来回收未使用的对象,以使其当前占用的内存可用于快速重用。当控制从方法调用返回时,Java虚拟机已尽最大努力从所有丢弃的对象中回收空间。
运行待完成的任何对象的终结方法。 调用此方法表明Java虚拟机花费了大量精力来运行已被发现被丢弃但尚未运行其finalize方法的对象的finalize方法。当控制从方法调用返回时,Java虚拟机已尽最大努力完成所有未完成的终结。
其次,Runtime.freeMemory()
记录为“返回近似值”
当前可用内存总量的近似值 未来分配的对象,以字节为单位。
第三,我知道你给“String”作为例子,但根据这个线程,在声明它们的类被卸载之前,字符串文字不会被垃圾收集。 Garbage collection of String literals
所以我认为它不是可以单元测试的东西。如果我想找到内存泄漏,我会使用分析器。