たとえば、大量のデータを含む変数を使用しましたString data
。この文字列の一部を次のように使用したいと考えました。
this.smallpart = data.substring(12,18);
数時間のデバッグ (メモリ ビジュアライザーを使用) の後、オブジェクト フィールドにはサブ文字列しか含まれていないにもかかわらず、smallpart
のすべてのデータが記憶されていることがわかりました。data
コードを次のように変更しました:
this.smallpart = data.substring(12,18)+"";
問題は解決しました。今では、アプリケーションが使用するメモリはごくわずかです。
どうしてそんなことが可能なのでしょうか? 誰か説明できますか? this.smallpart がデータを参照し続けていると思いますが、なぜでしょうか?
アップデート:では、大きな文字列をクリアするにはどうすればいいでしょうか? data = new String(data.substring(0,100)) でクリアできますか?
ベストアンサー1
次の操作を実行します。
data.substring(x, y) + ""
新しい (より小さい) String オブジェクトを作成し、substring() によって作成された String への参照を破棄して、これのガベージ コレクションを有効にします。
重要なのは、それsubstring()
が既存 文字列 - または、元の文字列の基礎となる文字配列。したがって、元の文字列と同じメモリを消費します。これは状況によっては有利ですが、部分文字列を取得して元の文字列を破棄する場合は問題になります (お分かりのとおり)。
見てみましょうsubstring() メソッド詳細については、JDK 文字列ソースを参照してください。
編集:補足の質問に答えると、部分文字列から新しい文字列を作成するとメモリ消費量が削減されます。提供された元の文字列への参照をすべて削除します。
注(2013年1月)。上記の動作は変更されましたJava 7u6の場合フライウェイト パターンは使用されなくなり、substring()
期待どおりに動作します。