3

サイズを固定するために removeEldestEntry メソッドを上書きするローカル FIFO キャッシュ ソリューションとして LinkedHashMap を使用しようとしています。

Map lhm = new LinkedHashMap(MAX_CACHE_SIZE + 1, .75F, false) {
   protected boolean removeEldestEntry(Map.Entry eldest) {
      return size() > MAX_CACHE_SIZE;
   }
};

しかし、マップ モニタリング プロセス メモリに常に新しいエントリを追加すると、マップ サイズは増加しませんが、最大仮想マシン メモリが使用されるまで増加し続けることがわかります。

それは設計によるものですか?古い値が破棄され、マップのサイズが制限されている場合、なぜより多くのメモリが必要になるのですか?

更新: 要求に応じて、完全なコードを添付しています:

@Test
public void mapMemory() {
    final int MAX_CACHE_SIZE = (int) 1E3;
    Map lhm = new LinkedHashMap(MAX_CACHE_SIZE + 1, 1F, false) {
       protected boolean removeEldestEntry(Map.Entry eldest) {
          return size() > MAX_CACHE_SIZE;
       }
    };

    for (long i = 0; i < 1E10; i++) {
        lhm.put("key_" + i, "VALUE");
    }
}
4

3 に答える 3

0

コレクションのコンテンツへのランダム アクセスが必要な場合、実際には FIFO ではありません。

ただし、コレクションはオブジェクトを格納するのではなく、重要な違いであるオブジェクトへの参照を格納することに注意してください。同じオブジェクトを 2 つの異なるコレクションに格納しても、大きなメモリ オーバーヘッドは発生しないため、同じオブジェクトをキューとマップの両方に格納するのが最善の解決策かもしれません。FIFO 動作が必要な場合はキューを使用し、ランダム アクセスが必要な場合はマップを使用します。 .

ただし、オブジェクトを使い終わったら、両方のコレクションからオブジェクトを削除することを忘れないでください。そうしないと、GC されません。

于 2013-10-28T12:54:39.473 に答える