• ベストアンサー

java string 配列の使用メモリ

String[][][] arg = = new String[x][x][x]; でxが638の時にjava.lang.OutOfMemoryErrorになってしまいます。 VM起動時のヒープ最大値は1GBまで試しましたがダメでした。 このときargオブジェクトはどれだけのメモリを必要とするのでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • SN1701
  • ベストアンサー率76% (16/21)
回答No.3

このnewで作られるオブジェクトは、配列オブジェクトだけです。Stringオブジェクト自体は作られません。 なので、オブジェクトのサイズとしては、配列オブジェクトのサイズだけを考えればよいことになります。 (ちなみに、メソッド本体はクラスに1つあるだけで、作成したオブジェクトの数だけできるわけではないですから、オブジェクトを作ると、新たにメソッドの分のメモリが必要になるわけではありません) さて、argオブジェクトのサイズですが、1つのオブジェクトへの参照を保持するのにまず何バイトが必要か考える必要があります。 32bitのJavaだったら、たぶん32bit=4バイトでしょう。 この配列の要素数はx^3個ですので、1つあたりが4バイトとなると、x^3 * 4 バイトのメモリが最低限必要ということになります。 もちろん、他にも多少メモリが必要でしょうが、xが大きいときのことを考えるわけですし、無視しても問題ないでしょう。 x=638の場合を計算してみると、638^3 * 4 = 1038776288 となります。 これは約990MB で、だいたい1GBです。 ヒープの最大値を1GBで試したということですので、計算と合っているのではないでしょうか。

glorian
質問者

補足

回答ありがとうございます。 >32bitのJavaだったら、たぶん32bit=4バイトでしょう。 この回答を示すページ等はありますか?

すると、全ての回答が全文表示されます。

その他の回答 (3)

  • salsberry
  • ベストアンサー率69% (495/711)
回答No.4

論より証拠、ヒープが足りる範囲で実際に測ってみればいいのです。 int n=1000; Runtime rt = Runtime.getRuntime(); long free1, free2; System.gc(); free1 = rt.freeMemory(); String[] arg = new String[n]; free2 = rt.freeMemory(); System.out.println("Free diff: " + (free1 - free2)); うちのJava環境では、n=1000のときの結果が4016、n=2000のときが8016でした。このことから、String[]の配列1要素あたり4バイト消費することが分かります。 他のJava環境では違うかもしれません。64ビット環境用のJavaだったら、おそらく1要素あたり8バイトになるでしょう。 なお、上のコードは手抜きです。本当はfreeMemory()だけじゃなくてtotalMemory()の値の変化も確認する必要があるはず。

すると、全ての回答が全文表示されます。
noname#94983
noname#94983
回答No.2

xが638って、まさかarg[638][638][638]ってことかね? 配列の全要素にStringインスタンスを保管する、ということだな。Stringリテラルではなくて。まぁ、実際にどれだけ使われているかはわからないが、ざっと概算で必要なメモリを計算してみると。 まず、arg[638][638][638]という時点で、259694072個のStringオブジェクトが保管されるだけのメモリが必要になることはわかるだろう。クラスというのは、マジックナンバー、バージョン、コンスタントプール、インターフェイス、フィールド、メソッド、属性リストの各エントリ数などが最低限必要で、全く何も中身がないインスタンスでも既に24byteほどメモリをしめる。完璧に空っぽのインスタンスであったとして、 638×638×638×24 = 6232657728byte = 約5.8GB と、ざっと6GBほどが必要いうことになる。これは中身が空っぽの状態であって、Stringには実際問題として多数のフィールドとメソッドがあるわけだから、まぁざっとこの10倍として、60GBぐらいか。 これに加えて、個々のString値の保管領域が必要となる。どのぐらいのテキストを保管するかによるが、平均10byte程度の文字列であったとしても数GBは必要になる。実際問題として、100GBぐらいはないと正常に動かすのは難しいかも知れない、という結論になるが。

glorian
質問者

補足

回答ありがとうございます。 >全く何も中身がないインスタンスでも既に24byteほどメモリをしめる。 この回答を示すページ等ありますでしょうか?

すると、全ての回答が全文表示されます。
回答No.1

>このときargオブジェクトはどれだけのメモリを必要とするのでしょうか? と言われても・・・ String[][][] arg = = new String[x][x][1]; を実行して消費するリソースの638倍を目安に考えればいいんじゃないですかね(オーバーヘッドや中身については考えていない)

すると、全ての回答が全文表示されます。

関連するQ&A