1

java-Xmx60gコマンドを使用して次のコードを実行しています。

各アレイは約8.5GB、合計17GBである必要があります。マシンの合計は64GBで、 63GBが「無料」です。DONE DECLARING RIVER HANDS 1最初の配列の宣言が終了したことを示す、を出力します。

しかし、スレッド "main" java.lang.OutOfMemoryErrorで例外が発生します:2番目の配列の宣言中にJavaヒープスペース。アレイは17GBしか使用しないのに対し、は60GB-Xmx60gを割り当てる必要があると理解しているため、混乱しています。

よろしくお願いします!

long NUM_RIVER_HANDS = 2428287420L;
int half_river = (int)(NUM_RIVER_HANDS/2);
byte[][] river_hands_1 = new byte[half_river][7];
System.out.println("DONE DECLARING RIVER HANDS 1");
byte[][] river_hands_2 = new byte[(int)(NUM_RIVER_HANDS - half_river)][7];
System.out.println("DONE DECLARING RIVER HANDS 2");
4

1 に答える 1

4

最初の割り当てでは、1214143710 個の配列を作成しています。それぞれの配列は 7 バイトにオブジェクト オーバーヘッドを加えたものです。16 バイトの配列のオブジェクトごとのオーバーヘッドを想定すると (これは妥当であり、保守的ではありません) 、スペースの3 分の 2 が無駄になっていることを意味します。配列ごとに合計 24 バイトを想定すると、最初の割り当てだけで ~29GB になります...そして、それよりも多くのオーバーヘッドがある場合は、配列ごとに 32 バイトに押し上げます。たとえば、それは ~38GB であり、その時点で2回できないことは驚くことではありません:)

配列の使用方法を変更して、これをより効率的にします。

// Names changed to follow Java naming conventions
byte[][] riverHands1 = new byte[7][halfRiver];
byte[][] riverHands2 = new byte[7][(int)(NUM_RIVER_HANDS - halfRiver)];

配列の使用方法も変更する必要がありますが、合計 14個のbyte[]オブジェクトがあり、それぞれが非常に大きくなっています... しかし、オブジェクトのオーバーヘッドによる無駄なメモリはほとんどありません。

于 2013-02-20T14:55:30.120 に答える