15

次のプログラムを実行すると(で実行"java -Xmx151M -cp . com.some.package.xmlfun.Main"):

package com.some.package.xmlfun;
public class Main {

    public static void main(String [] args) {
        char [] chars = new char[50 * 1024 * 1024];

    }
}

最大メモリを少なくとも 151M (-Xmx151M) に増やす必要があります。したがって、配列サイズを増やすと、制限を増やす必要があります。

  • 50 * 1024 * 1024 -> -Xmx151M
  • 100 * 1024 * 1024 -> -Xmx301M
  • 150 * 1024 * 1024 -> -Xmx451M

ドキュメントが示唆するように、Java が 1 文字あたり 2 バイトではなく 3 バイトを必要とするように見えるのはなぜですか?

また、同様に long の配列を作成すると、long ごとに 8 ではなく 12 バイトが必要なようです。int では、4 ではなく 6 バイトが必要です。一般的には、array_size * element_size * 1.5 が必要なようです。

でコンパイル- javac \com\som\package\xmlfun\\*java

で実行- java -Xmx151M -cp . com.some.package.xmlfun.Main

4

4 に答える 4

6

Java HotSpot VM では、ヒープを「新世代」と「旧世代」に分けています。配列は、それらのいずれかにある必要があります。新世代/旧世代サイズの比率のデフォルト値は 2 です。 (これは実際には を表しますold/new=2)

したがって、いくつかの簡単な計算で、151MB のヒープが 50.33MB の新しい世代と 100.67MB の古い世代を持つことができることを示すことができます。また、150MB ヒープにはちょうど 100MB の古い世代があります。配列 + 他のすべて ( などargs) で 100MB が使い果たされるため、 が生成されOutOfMemoryErrorます。


で走ってみました

java -Xms150m -Xmx150m -XX:+PrintGCDetails Main > c.txt

そしてからc.txt

(...)
ヒープ
 PSYoungGen 合計44800K、使用 3072K (アドレス...)
  eden スペース 38400K、8% 使用済み (...)
  スペース 6400K から、使用率 0% (...)
  スペース 6400K まで、使用率 0% (...)
 ParOldGen 合計102400K、使用 217K (...)
  オブジェクト スペース 102400K、使用率 0% (...)
 PSPermGen 合計 21248K、使用 2411K (...)
  オブジェクトスペース 21248K、11% 使用済み (...)

スペースは私の計算と正確には一致しませんが、近いです。

于 2013-06-27T14:04:57.017 に答える
1

(Visual GC などを使用して) データのサイズを見ると、配列のサイズが 1 文字あたり 2 バイトであることがわかります。

ここでの問題は、JVM がヒープの古い世代に配列全体を収めようとすることであり、この世代のサイズは新世代と旧世代のサイズの比率によって制約されます。

で実行する-XX:NewRatio=5と、問題が修正されます (デフォルト値は 2 です)。

于 2013-06-27T14:09:57.540 に答える
0

ブルーノの答えに基づいて構築しようとします。私は今このコードを試しました:

public static void main(String[] args) throws IOException {
    char [] chars = new char[50 * 1024 * 1024];
    System.out.println(Runtime.getRuntime().freeMemory());
    System.out.println(Runtime.getRuntime().totalMemory());
    System.out.println(Runtime.getRuntime().maxMemory());
}

出力は次のとおりです。

38156248
143654912
143654912

JVM の他の目的のために 40 MB が空いたままになっていることは明らかです。私の最善の推測は、新世代のスペースです。

于 2013-06-27T14:10:21.790 に答える