此Java示例是否会导致内存泄漏?

Bac*_*chT 17 java memory-leaks

我有一个简单的例子.该示例ArrayList<Integer>f包含10000000个随机整数的文件加载an .

doLog("Test 2");
{
    FileInputStream fis = new FileInputStream(f);
    ObjectInputStream ois = new ObjectInputStream(fis);
    List<Integer> l = (List<Integer>) ois.readObject();
    ois.close();
    fis.close();
    doLog("Test 2.1");
    //l = null; 
    doLog("Test 2.2");
}
doLog("Test 2.3");
System.gc();
doLog("Test 2.4");
Run Code Online (Sandbox Code Playgroud)

当我有l = null,我得到这个日志:

Test 2                          Used Mem = 492 KB   Total Mem = 123 MB
Test 2.1                        Used Mem = 44 MB    Total Mem = 123 MB
Test 2.2                        Used Mem = 44 MB    Total Mem = 123 MB
Test 2.3                        Used Mem = 44 MB    Total Mem = 123 MB
Test 2.4                        Used Mem = 493 KB   Total Mem = 123 MB
Run Code Online (Sandbox Code Playgroud)

但是当我删除它时,我得到了这个日志.

Test 2                          Used Mem = 492 KB   Total Mem = 123 MB
Test 2.1                        Used Mem = 44 MB    Total Mem = 123 MB
Test 2.2                        Used Mem = 44 MB    Total Mem = 123 MB
Test 2.3                        Used Mem = 44 MB    Total Mem = 123 MB
Test 2.4                        Used Mem = 44 MB    Total Mem = 123 MB
Run Code Online (Sandbox Code Playgroud)

Used Memory 计算方法是: runTime.totalMemory() - runTime.freeMemory()

问题:如果l = null;存在,是否存在内存泄漏? l是无法进入的,为什么它不能被释放?

Kep*_*pil 28

上面的代码中没有内存泄漏.

一旦你将代码块放在其中{},变量l就会超出范围,并且它List是垃圾收集的候选者,无论你是否将其设置为nullfirst.

但是,在代码块之后直到返回方法,List处于一种称为不可见的状态.虽然这是事实,但JVM不太可能自动使引用无效并收集List内存.因此,显式设置l = null可以帮助JVM在进行内存计算之前收集内存.否则,它将在方法返回时自动发生.

对于不同的代码运行,您可能会得到不同的结果,因为您永远不知道垃圾收集器何时运行.你可以建议你认为它应该运行System.gc()(甚至可以在List没有设置的情况下收集隐形l = null),但是没有任何承诺.它在System.gc()javadoc中声明:

调用gc方法表明Java虚拟机花费了大量精力来回收未使用的对象,以使其当前占用的内存可用于快速重用.当控制从方法调用返回时,Java虚拟机已尽最大努力从所有丢弃的对象中回收空间.

  • 换句话说,编译代码时,花括号不会有任何内容. (2认同)