0
public class Bad {
    public static void main(String[] args) {
        Integer[] buff = new Integer[5000000];
        int i = 0;
        while (true) {
            i++;
            if (i == buff.length)
                i = 0;
            Integer obj = new Integer(i); // line 14
            buff[i] = obj;
            // do something useful with buff[i];
        }
    }
}

几秒钟后意外终止,并在命令行打印以下消息:线程“main”中的异常 java.lang.OutOfMemoryError: Java heap space at Exam.Bad.main(Bad.java:14)

谁能解释一下出了什么问题,请给我提供解决问题的代码?

4

3 回答 3

3

您只是用完了堆空间。
简而言之,堆是内存的(有限)部分,当您执行new指令时会在其中分配动态数据。

Integer[] buff = new Integer[5000000];

将分配很大一部分堆空间,并且在您的循环中,Integer obj = new Integer(i);将分配更多堆内存直到限制(这是异常的原因)。

-Xmx 设置最大Java堆大小

选项(用于 java 命令)您可以分配更大的堆空间

编辑(关于您的代码):

for(int i=0;i < buff.length;i++) {
  if (i == buff.length) {
    // But this is only an hint to perform garbage as soon as possible
    System.gc();
    i = 0;
  }
  Integer obj = new Integer(i); // line 14
  buff[i] = obj;
  // do something useful with buff[i];
}

但是你有(可能)最大化堆空间让它工作,这取决于垃圾何时执行

于 2013-08-26T21:08:01.950 回答
1

您有一个无限循环 while(true)
,并且您在循环中的堆上创建对象

Integer obj = new Integer(i);

所以你用完了堆空间。

你还没有告诉我们你的代码做了什么,但是你需要在某个时候打破循环或者有一个条件会返回 false。由于您只是一遍又一遍地遍历循环,除了重置数组中的元素之外,您可能只想遍历一次而不是将 i 重置为 0

于 2013-08-26T21:05:33.707 回答
0

你必须放一个,但在擦除代码break;后你有一个错误的操作:if (i == buff.length)i = 0;

这是我认为可以帮助您的代码:

public class Bad {
    public static void main(String[] args) {
        Integer[] buff = new Integer[500];
        int i = 0;
        while (true) {
            Integer obj = new Integer(i); // line 14
            buff[i] = obj;
            // do something useful with buff[i];
            //After do something use a coditional to break the loop like this
             i++;
            if(i>=buff.length){i = 0;break;}

        }
    }
}
于 2013-08-26T21:43:01.327 回答