2013-10-11 11 views
5

サイズが10桁の整数であるブール型の配列を初期化しようとしています。 OutOfMemoryExceptionを投げつけ続けます。私は日食のヒープスペースのサイズを256から1024に増やしました。私は行方不明のものはありますか? docsjava.lang.OutOfMemoryError:配列を初期化する際のJavaヒープスペース

This data type represents one bit of information, but its "size" isn't something that's precisely defined.

から

int size = 1000000000; 
boolean[] primesList = new boolean[size]; 
+4

大量のスペースが必要ですか? – Reddy

+0

最初に数えます:サイズ* 4バイト+他のオブジェクト。代わりに[Buffer](http://docs.oracle.com/javase/7/docs/api/java/nio/Buffer.html)を使用してください。 –

+0

@ajozwikサイズ* 4バイトはどこで取得できましたか? – Kayaman

答えて

11

使用java.util.BitSetの最大サイズを有することに注意してください。

ブール配列要素が1ビットではなく1バイトを使用するのは、(ほとんどの)CPUアーキテクチャが個々のビットを直接読み書きできるためです。最小単位のPCは8ビットの操作が可能です。 JVM ビットをまとめてパックすることができますし、ビットを変更して変更して書き戻すことができますが、複数のスレッドが同時に配列を変更している場合は動作しません。

元のアレイでは、10億ブールで、1バイトごとに10億バイトまたは954 MBです。したがって、1024 MBのヒープで十分であるはずです(?)。おそらく、連続したのチャンクが見つからないか、メモリパラメータを正しく設定していない可能性があります。 Runtime.getRuntime().maxMemory()の値を出力して、Javaが使用している最大ヒープ・サイズを調べます。 1024 MBの場合、パラメータは-Xmx1024Mである必要があります。

最終ノート:Java 7では、アンダースコアを数値で読みやすくすることができます。したがって、1000000000の代わりに1_000_000_000と書くことができます。

2

あなたはブールのために少なくとも1バイト、その1000000000バイトを検討している場合は、使用しているアレイの953MBメモリを必要とします。

これは、953MB1024MBを食べている唯一のアレイなので、問題の原因になる可能性があります。

しかし、良い世界では、このユースケースは、私はJVMを起動すると、あなたが高いとして最大ヒープ領域を設定するには、-Xmxパラメータを渡す必要があります:)

+0

あなたはそこにゼロを追加しました。そして、少なくともこの形式では、ブール値は1ビットを取っていません。 – Kayaman

+0

あなたは誤算しました。 11桁ではなく10桁の数字があります。 –

+0

@ViktorOzerovはい、そうです。余分なゼロは削除されました。指してくれてありがとう。 –

0

推測する必要はありません。

もアレイがbooleanアレイを使用する場合に比べスペースの1/8のビットをパックするInteger.MAX_VALUEの

0

オブジェクトホルダを代わりに使用して、すべての領域を一度に割り当てる必要がなくなります。ヒープサイズが十分に大きい場合は、問題を回避できます。多くのブール値を配列内に保持するためには、多くのスペースが必要です。ヒープスペースの最小サイズと最大サイズが設定されていることを確認してください。 Listのようなものを使用して、必要なときだけ値を入力します。配列として実際に必要な場合は、変換する方法があります(Apacheコモンの配列コレクションではArrays.toPrimitiveを使用できます)。

0

ブール配列は、バイトとして格納されます。

https://forums.oracle.com/thread/2550321

私はあなたがこれをやっている方法を再考する必要があると思う - 現在のハードウェアの能力を超えているギガバイトのためにサイズのデータ​​構造を作成します。

1

もっと多くのヒープサイズを要求するだけです。例えば、-X1500Mは間違いなく動作します。あなたの配列は1000000000バイトを占めますが、Javaヒープは新しい+古い世代に分割されているため、さらにリクエストする必要があります。それは、次の2つの理由に非常によくすることができ

0

this記事によると

  1. 、JVMは、あなたのプログラムに全体Xmxの量を割り当てません。サバイバー・スペースの1つが占めるスペースは、JVMがいくつかの簿記または一時的な使用のために内部的に使用するため、割引されます。これは、配列がすでに954 MBを使用しているため、1024 MBが十分でない理由です。生存者のスペースは70 MB以上になる可能性があります。 Xmxを増やすことは、以下の点で説明されているように役立つ場合もあれば、役に立たない場合もあります。

  2. 記事によれば、データ構造がヒープ内のどの世代でも大きすぎる場合は、 、古い世代)。 -XX:+ PrintGCDetailsを使用して、世代ごとにどれだけ多くのものが得られているかを確認できます。そのため、少なくとも1つ(eden、from/to、old gen)がオブジェクトを保持するのに十分な大きさになるか、別のヒープ領域のサイズを明示的に設定する必要があるまで、Xmxを増やさなければなりません(例: XX:若い世代のためのNewSize)。

関連する問題