のJavaドキュメント(jdk1.8.0_71)は、 は、通常使用されなくなった、キーのない場合WeakHashMap
で
エントリは自動的に削除されます、と言っています。より正確には、指定されたキーのマッピングが であることは、ガーベジコレクタによってキーが破棄されるのを妨げません。
これは明らかにkey
が破棄されたとき、そのEntry<K, V>
もMap
から削除されることを述べています。
ここで、key
が取り外されたときの状況を確認してください。以下に示すようremove(Object o)
方法の コードスニペットは:
public V remove(Object key) {
Object k = maskNull(key);
int h = hash(k);
Entry<K,V>[] tab = getTable();
int i = indexFor(h, tab.length);
Entry<K,V> prev = tab[i];
Entry<K,V> e = prev;
while (e != null) {
Entry<K,V> next = e.next;
if (h == e.hash && eq(k, e.get())) {
modCount++;
size--;
if (prev == e)
tab[i] = next;
else
prev.next = next;
return e.value;
}
prev = e;
e = next;
}
return null;
}
ことが観察できるように、この方法は、第一getTable()
メソッドを呼び出すことにより、Entry<K, V>
のアレイを取り込みます。 getTable()
へのすべての呼び出しで、別の方法expungeStaleEntries()
が呼び出されます。この特定の方法は、WeakEntries
をクリアして保持しているReferenceQueue<Object>
で再生し、のから古いエントリを削除します。このメソッドのコードスニペットは、以下に見ることができる。
/**
* Expunges stale entries from the table.
*/
private void expungeStaleEntries() {
for (Object x; (x = queue.poll()) != null;) {
synchronized (queue) {
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>) x;
int i = indexFor(e.hash, table.length);
Entry<K,V> prev = table[i];
Entry<K,V> p = prev;
while (p != null) {
Entry<K,V> next = p.next;
if (p == e) {
if (prev == e)
table[i] = next;
else
prev.next = next;
// Must not null out e.next;
// stale entries may be in use by a HashIterator
e.value = null; // Help GC
size--;
break;
}
prev = p;
p = next;
}
}
}
}
それがコードスニペットを介して見ることができるように、各エントリは、put(K, V)
中にこのqueue
(呼び出すコンストラクタでWeakHashMap
、店舗そのエントリに追加される、こと
Entry<K,V> e = tab[i];
tab[i] = new Entry<>(k, value, queue, h, e);
)と同じエントリがEXPUNGE動作中queue
から取り出され、除去される。動作は、以下に示す通りです。この値が削除されたEntry<K, V>
はnull e.value = null
に設定され、GC'dとなります。そして、はい、それはGCを制御しません。これは、WeakHashMap
がキーでマップされた値を破棄するのを容易にする方法です。
メモリの解放は、必要に応じてガーベッジコレクタによって行われます。特定の時間にメモリが解放される保証はありません。それはガベージコレクタの実装までです。通常、そのような強い保証は必要ありません。 GCがその仕事をして、それについて心配しないでください。 – Jesper
これはgc関数が現在よく知られていると理解しています。私は週ハッシュマップの専門性について疑問を抱いていた。 –