OutOfMemoryErrorの系列(7):要求された配列のサイズは、VM制限を超え
HTTPS:// blog.csdn.net/renfufei/article/details/78170188
これは、このシリーズの第七の記事、関連する記事の一覧です。
- OutOfMemoryErrorの系列(1):Javaのヒープスペース
- OutOfMemoryErrorの系列(2):GCオーバーヘッド制限を超え
- OutOfMemoryErrorの系列(3):Permgenスペース
- OutOfMemoryErrorの系列(4):メタスペース
- OutOfMemoryErrorの系列(5):新しいネイティブスレッドを作成できません。
- OutOfMemoryErrorの系列(6):スワップ領域のうち?
Javaプラットフォームは、配列の最大長さを制限します。各バージョンの特定の制限がわずかに異なることができるが、範囲であってもよい 1 ~ 21亿
との間。
プログラムがスローした場合 java.lang.OutOfMemoryError: Requested array size exceeds VM limit
、エラーが、それはあなたが長さの配列が制限を超えて作成することを意味します。
原因分析
データ構造プラットフォームは、あなたよりももちろん(アドレス指定可能)、この間違いに対処できるかどうかに割り当てる:このエラーは、実際には配列のためのメモリを割り当てる前に投げJVMネイティブ・コードによって引き起こされる、JVMは、チェックを実行します。それはあまり一般的だろうと思いました。
まれ添字(インデックス、インデックス)配列としてJavaを使用してINTため、このエラーが表示されません。Javaでは、最大値はint型です 2^31 – 1 = 2,147,483,647
。ほとんどのプラットフォーム上の制限は、この値にほぼ等しくされている-例えば、プロの64ビットMBに、Java(登録商標)1.7プラットフォームの長さを割り当てることができる 2,147,483,645
だけでなく、 Integer.MAX_VALUE-2
)アレイ。
なる、少し長さを追加し Integer.MAX_VALUE-1
、我々はそれを知っているように、それがスローされます、 OutOfMemoryError
。
`Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exceeds VM limit`
いくつかのプラットフォームでは、この上限も小さく、例えば、32 Linuxでは、上記のOpenJDK 6であってもよく、周りに11億(約の配列の長さは2^30
)「スローするjava.lang.OutOfMemoryError: Requested array size exceeds VM limit
エラー」。特定の限界値を見つけるために、小テストを行うことができ、以下の具体的な実施例を参照してください。
例
以下のコードを実証するために使用される java.lang.OutOfMemoryError: Requested array size exceeds VM limit
エラー:
for (int i = 3; i >= 0; i--) {
try { int[] arr = new int[Integer.MAX_VALUE-i]; System.out.format("Successfully initialized an array with %,d elements.\n", Integer.MAX_VALUE-i); } catch (Throwable t) { t.printStackTrace(); } }
ここで、4回反復ループ、長からintの配列を初期化するたびに Integer.MAX_VALUE-3
増分は、へ Integer.MAX_VALUE
のMac OS Xプラットフォームのホットスポット7に64まで、コードは次のようなこのような結果を実行します。
java.lang.OutOfMemoryError: Java heap space
at eu.plumbr.demo.ArraySize.main(ArraySize.java:8) java.lang.OutOfMemoryError: Java heap space at eu.plumbr.demo.ArraySize.main(ArraySize.java:8) java.lang.OutOfMemoryError: Requested array size exceeds VM limit at eu.plumbr.demo.ArraySize.main(ArraySize.java:8) java.lang.OutOfMemoryError: Requested array size exceeds VM limit at eu.plumbr.demo.ArraySize.main(ArraySize.java:8)
スロー2回の反復の後に注意してくださいという java.lang.OutOfMemoryError: Requested array size exceeds VM limit
エラーの前に、最初の2回をくぼんだ java.lang.OutOfMemoryError: Java heap space
間違いました。これは、 2^31-1
int型のメモリの数は8GBのデフォルトのJVMのヒープメモリ以上で占められて。
ほぼ長さに等しく割り当てる配列JVMのサイズに制限を取得する-この例では、このミスの比較的まれな原因を示し Integer.MAX_INT
、この例ではアレイの64ビットMAC OS X、ホットスポット7プラットフォーム、2つだけの長さを実行しています。私は、このエラーがスローされます Integer.MAX_INT-1
と Integer.MAX_INT
。
ソリューション
発生 java.lang.OutOfMemoryError: Requested array size exceeds VM limit
エラーの原因は次のようになります。
- アレイが大きすぎると、プラットフォームの最終的な長さが限界値を超え、未満
Integer.MAX_INT
- システムの制限割当長さをテストするには意図的により大きい
2^31-1
アレイ。
最初のケースでは、あなたが本当に大きな配列を必要とするかどうかをサービスコード、確認をチェックする必要があります。配列の長さを低減することができる場合は、すべてのウェルである。そうでない場合、データを複数のブロックに分割する必要があり、必要に応じてその後のバッチにロードされてもよいです。
後者の場合ならば、指標としてのint値を持つJava配列を覚えています。したがって、アレイ要素以上にすることはできません 2^31-1
1。実際には、コードは、コンパイル時にメッセージをエラーますerror: integer number too large
「」
。あなたが大規模なデータセットを処理する必要を行う場合は、それが複数の小片にソリューション分割を調整することを検討しなければならない、例えば、バッチでロードされた、または標準ライブラリの使用を放棄するが、そのプロセスデータ構造、などの使用など、 sun.misc.Unsafe
安全でないことで、クラス、 Cのような簡単な言語は、メモリを割り当てるなどのツールをすることができます。
オリジナルリンク: https://plumbr.eu/outofmemoryerror/requested-array-size-exceeds-vm-limit
翻訳日:2017年9月21日