9

重複する文字列がたくさんあるアプリケーションに取り組んでいます。私のタスクは、それらを削除してメモリ使用量を減らすことです。私の最初の考えはString.intern、文字列の参照が1つだけ存在することを保証するために使用することでした。ヒープメモリを減らすために機能しましたが、PermGenを大幅に増やしました。実際、一度だけ宣言される文字列が多いため、実際には、アプリケーションが使用するメモリの総量が増加しました。

別のアイデアを検索した後、私はこのアプローチを見つけました:https ://stackoverflow.com/a/725822/1384913 。

String.internと同じことが起こりました。文字列の使用量は減少しましたが、保存したメモリはクラスWeakHashMapWeakHashMap$Entryクラスで使用されています。

回復しているのと同じ量のメモリを消費しない文字列ごとに1つの参照のみを維持する効果的な方法はありますか?

4

3 に答える 3

1

に代わるものを見つけましたWeakHashMapWeakHashSetEclipse JDTライブラリによって提供されます。と同じ動作ですWeakHashMapが、使用するメモリが少なくなります。また、メソッドを呼び出すだけでadd、文字列がまだ存在しない場合はセットに追加され、そうでない場合は既存の文字列が返されます。

私が気に入らなかった唯一のことは、ジェネリックを使用しないという事実であり、開発者はオブジェクトをキャストする必要がありました。以下に示すように、私のintern方法は非常に単純であることがわかりました。

の宣言WeakHashSet:

private static WeakHashSet stringPool = new WeakHashSet(30000); //30 thousand is the average number of Strings that the application keeps.

そしてインターンメソッド:

public static String intern(String value) {
    if(value == null) {
        return null;
    }
    return (String) stringPool.add(value);
}
于 2012-10-16T17:07:40.703 に答える
0

同様のケースで、可能な限り文字列定数を列挙型にリファクタリングしました。これにより、次の 2 つの利点が得られます。

  • enum インスタンスはシングルトンであるため、メモリの問題は発生しません
  • 文字列を使用する場合のタイプミスはありません。

短所:

  • 十分なテストケースがない場合、間違いを犯す可能性が無限にある多くの作業
  • たとえば、編集できないサードパーティのライブラリとやり取りする必要がある場合など、これは簡単なことではありません...
  • これらが実行時に決定され、コンパイル時間ではない場合は、単にノーゴーです...
于 2012-10-16T09:57:11.487 に答える
0

String の代わりに StringBuilder/StringBuffer クラスを使用しないでください。このクラスのインスタンスを使用すると、同じインスタンスを異なる値でいつでも使用できます。- アンクル

于 2012-10-16T09:40:57.817 に答える