8

特注のワイヤ プロトコルを使用して TCP 経由で送信されたメッセージを処理するコーデックを作成しています。デコード プロセス中に、多数Stringの 、 、BigDecimalおよび日付を作成します。クライアント/サーバー アクセス パターンは、クライアントがリクエストを発行し、何千ものレスポンス メッセージをデコードすることが一般的であることを意味しますStringBigDecimal

したがってInternPool<T>、オブジェクトの各クラスをインターンできるクラスを作成しました。内部的に、プールはWeakHashMap<T, WeakReference<T>>. 例えば:

InternPool<BigDecimal> pool = new InternPool<BigDecimal>();

...

// Read BigDecimal from in buffer and then intern.
BigDecimal quantity = pool.intern(readBigDecimal(in));

私の質問: InternPoolforを使用していますが、PermGen スペースを使用すると思われる'sメソッドの代わりにBigDecimalfor を使用することも検討する必要がありますか? PermGen スペースを使用する利点は何ですか?String Stringintern()

4

2 に答える 2

5

そのようなInternPoolクラスが既にある場合は、文字列に対して別のインターン方法を選択するよりも、それを使用する方がよいと考えられます。特に、String.intern()実際に必要とするよりもはるかに強力な保証を提供しているようです。あなたの目標はメモリ使用量を減らすことなので、JVM の存続期間中の完全なインターンは実際には必要ありません。

また、ホイールの再作成を避けるために、 Google Collections MapMakerを使用して を作成します。InternPool

Map<BigDecimal,BigDecimal> bigDecimalPool = new MapMaker()
    .weakKeys()
    .weakValues()
    .expiration(1, TimeUnits.MINUTES)
    .makeComputingMap(
      new Function<BigDecimal, BigDecimal>() {
        public BigDecimal apply(BigDecimal value) {
          return value;
        }
      });

これにより、(正しく実装された)弱いキーと値、スレッドセーフ、古いエントリの自動パージ、および非常に単純なインターフェース(単純でよく知られているMap)が得られます。Collections.immutableMap()悪いコードがそれをいじるのを避けるために、 を使用してラップすることもできます。

于 2010-05-19T11:39:03.197 に答える
3

JVM のString.intern()プールが高速になる可能性があります。私の知る限り、それはネイティブコードで実装されているため、WeakHashMapを使用して実装されたプールよりも高速で、使用するスペースが少なくて済みますWeakReference。これを確認するには、慎重にベンチマークを行う必要があります。

ただし、存続期間の長い複製オブジェクトが大量にない限り、インターン (permGen または独自のプールのいずれか) が大きな違いを生むとは思えません。また、一意オブジェクトと重複オブジェクトの比率が低すぎる場合、インターンはライブ オブジェクトの数を増やすだけで (GC の時間が長くなります)、インターンのオーバーヘッドなどによりパフォーマンスが低下します。したがって、「インターン」と「インターンなし」のアプローチのベンチマークも推奨します。

于 2010-05-19T12:14:02.363 に答える