私はAleksey Shipilevのスライド「The String catechism」(https://shipilev.net/talks/joker-Oct2014-string-catechism.pdf、49ffのスライド)で「重複排除剤」の概念を見つけました。多くのJavaプログラマーは、String.intern()のインターンと同様の概念を知っています。
ただし、弱参照が使用されていないと、重複排除器がメモリリークの可能性があります。 弱いハッシュマップを持つ重複排除器の正しい実装がどのように見えるのだろうか。私はオプションBになりがちですが、わかりません。弱いハッシュマップを持つ重複排除器の正しい実装は何ですか?
オプションA: WeakHashMapを使用すれば十分です。 「弱いキー」は、オブジェクトがもはや使用されなくなったときに削除されることを保証する。
サンプル実装:
public class SimpleWeakHashMapDeduplicator {
private final WeakHashMap<Object, Object> weakHashMap = new WeakHashMap<>();
public Object deduplicate(Object potentialDuplicate) {
if(potentialDuplicate == null) {
return null;
} else {
return weakHashMap.computeIfAbsent(potentialDuplicate, (key)->key);
}
}
}
オプションB: のWeakHashMapを使用するには十分ではありません。 ComplicatedWeakHashMapDeduplicatorのインスタンスは、1つのエントリが値を強く参照するエントリを持つ配列を強く参照する弱いハッシュマップを強く参照するため、すべての値はWeakReferenceでなければなりません。キーだけがマップによって弱く参照されます。どこが間違っていますか?
サンプル実装:
public class ComplicatedWeakHashMapDeduplicator {
private final WeakHashMap<Object, WeakReference<Object>> weakHashMap = new WeakHashMap<>();
public Object deduplicate(Object potentialDuplicate) {
if(potentialDuplicate == null) {
return null;
} else {
return weakHashMap.computeIfAbsent(potentialDuplicate, WeakReference::new).get();
}
}
}
あなたはどう思いますか?
WeakReferenceベースの文字列キャッシュは実用的ではありません。あまりにも多くのメモリを消費します。 WeakReferenceはGC時間に大きな影響を与える可能性があります。 –
[Guava WeakInterner](https://google.github.io/guava/releases/19.0/api/docs/com/google/common/collect/Interners.html#newWeakInterner())を参照してください。 – maaartinus
このようなマップは、少数の重複オブジェクトよりもはるかに多くのメモリを消費する可能性があります。 – Holger