如何使java内存泄漏的junit测试通过?

k3b*_*k3b 5 java junit memory-leaks

我有一个可能分配大量数据的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);
}
Run Code Online (Sandbox Code Playgroud)

有什么想法如何修改 junittest 以检查内存泄漏吗?

[更新]

不幸的是,9 岁的可能重复并没有为我的问题提供解决方案

我更改了标题和内容,使其比“可能的重复候选人”更具体

mis*_*der 4

使用单元测试测试内存泄漏时存在几个问题;
首先,在Javadoc中,运行似乎System.gc()System.runFinalization()不能保证收集和终结的发生,因为它提到“尽力而为”

调用 gc 方法表明 Java 虚拟机会努力回收未使用的对象,以使它们当前占用的内存可供快速重用。当控制权从方法调用返回时,Java 虚拟机已尽最大努力从所有丢弃的对象中回收空间。

运行任何挂起终结的对象的终结方法。调用此方法表明 Java 虚拟机花费精力来运行已发现已被丢弃但尚未运行其 Finalize 方法的对象的 Finalize 方法。当控制权从方法调用返回时,Java 虚拟机已尽最大努力完成所有未完成的终结。

其次,Runtime.freeMemory()记录为“返回近似值”

当前可用于将来分配的对象的内存总量的近似值(以字节为单位)。

第三,我知道您以“String”为例,但根据此线程,在声明它们的类被卸载之前,字符串文字不会被垃圾收集。字符串文字的垃圾收集

所以我不认为这是可以进行单元测试的东西。如果我想找到内存泄漏,我会使用分析器。