重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

電子書籍の厳選無料作品が豊富!

String[][][] arg = = new String[x][x][x];
でxが638の時にjava.lang.OutOfMemoryErrorになってしまいます。
VM起動時のヒープ最大値は1GBまで試しましたがダメでした。

このときargオブジェクトはどれだけのメモリを必要とするのでしょうか?

A 回答 (4件)

この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で試したということですので、計算と合っているのではないでしょうか。

この回答への補足

回答ありがとうございます。

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

補足日時:2009/05/12 14:57
    • good
    • 0

論より証拠、ヒープが足りる範囲で実際に測ってみればいいのです。



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()の値の変化も確認する必要があるはず。
    • good
    • 0

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ぐらいはないと正常に動かすのは難しいかも知れない、という結論になるが。

この回答への補足

回答ありがとうございます。

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

補足日時:2009/05/12 14:55
    • good
    • 0

>このときargオブジェクトはどれだけのメモリを必要とするのでしょうか?



と言われても・・・

String[][][] arg = = new String[x][x][1];

を実行して消費するリソースの638倍を目安に考えればいいんじゃないですかね(オーバーヘッドや中身については考えていない)
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!