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];
        }
    }
}

数秒後に予期せず終了し、次のメッセージがコマンド ラインに出力されました。

誰が何が問題だったのか説明できますか? 問題を解決するためのコードを教えてください。

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;後に 1 つの悪い操作があります。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 に答える