注释 for 循环时程序出错

Program gives error when for loop is commented

我在我的 java 程序中发现了一个奇怪的行为,我的代码看起来像这样

public class JavaTest {

    private final int dataSize = (int) (Runtime.getRuntime().maxMemory() * 0.6);

    public void test() {
        {
            System.out.println(dataSize);
            byte[] data = new byte[dataSize];
        }

//      for (int i = 0; i < 10; i++) {
//          System.out.println("Please be so kind and release memory");
//      }

        System.out.println(dataSize);
        byte[] data2 = new byte[dataSize];
    }

    public static void main(String[] args) {
        JavaTest jmp = new JavaTest();
        jmp.test();
    }
}

在这里,当我评论 for 循环时,我得到 Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 我可以理解 jvm 堆空间已满。

但是 在我的代码 中使用那个 for 循环,它可以正确执行。怎么来的?

我认为这是因为你在 { } 块中声明了 byte[] data,这意味着 data 的范围在代码块结束时结束。在取消注释循环的情况下,您可能会为垃圾收集器留出时间来释放 data 占用的内存。当您注释掉循环时,GC 还没有时间释放该内存。

如果您删除 data 声明周围的 { },它也会抛出 OutOfMemoryException,即使没有注释循环。

更新

This blog post 在@SubOptimal 的评论中陈述证明这个理论是错误的,看起来它与 GC 释放内存所需的时间没有任何关系。我会引用博客中的相关部分

The majority of responses were incorrect and suggested that the for() loop either gave the GC time to do its work during the System.out.println()...

Some of my readers realised that it had nothing to do with the System.out.println and that a simple int i = 0; would suffice. If you declare any local variable immediately after the code block, you break the strong reference to the byte[] held in the stack frame 1 before you invoke the new byte[] the second time.