当循环被评论时,程序给出错误

时间:2015-01-12 13:52:40

标签: java out-of-memory

我在我的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堆sapce已满。

在我的代码中使用for循环,它会正确执行。怎么来的?

1 个答案:

答案 0 :(得分:6)

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

如果您在{ }声明周围移除data,即使循环取消注释,它也会抛出OutOfMemoryException

<强>更新

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

  

大多数回复都不正确,并建议for()循环要么让GC时间在System.out.println()...

期间完成其工作。      

我的一些读者意识到它与System.out.println无关,而且一个简单的int i = 0;就够了如果在代码块之后立即声明任何局部变量,则在第二次调用新字节[]之前,中断对堆栈帧中保存的byte []的强引用 1。