Смайлы Вкл.
В следующем примере кода, когда ключи установлены на нуль и вызывается System.gc()
, WeakHashMap
теряет все сопоставления и освобождается.
class WeakHashMapExample {
public static void main(String[] args) {
Key k1 = new Key("Hello");
Key k2 = new Key("World");
Key k3 = new Key("Java");
Key k4 = new Key("Programming");
Map<Key, String> wm = new WeakHashMap<Key, String>();
wm.put(k1, "Hello");
wm.put(k2, "World");
wm.put(k3, "Java");
wm.put(k4, "Programming");
k1=null;
k2=null;
k3=null;
k4=null;
System.gc();
System.out.println("Weak Hash Map :"+wm.toString());
}
}
class Key{
private String key;
public Key(String key) {
this.key=key;
}
@Override
public boolean equals(Object obj) {
return this.key.equals((String)obj);
}
@Override
public int hashCode() {
return key.hashCode();
}
@Override
public String toString() {
return key;
}
}
Output: Weak Hash Map :{}
Когда WeakHashMap
используется вместе с HashMap
, а для ключей установлено значение null, WeakHashMap
не теряет сопоставления значений ключа.
class WeakHashMapExample {
public static void main(String[] args) {
Key k1 = new Key("Hello");
Key k2 = new Key("World");
Key k3 = new Key("Java");
Key k4 = new Key("Programming");
Map<Key, String> wm = new WeakHashMap<Key, String>();
Map<Key, String> hm=new HashMap<Key, String>();
wm.put(k1, "Hello");
wm.put(k2, "World");
wm.put(k3, "Java");
wm.put(k4, "Programming");
hm.put(k1, "Hello");
hm.put(k2, "World");
hm.put(k3, "Java");
hm.put(k4, "Programming");
k1=null;
k2=null;
k3=null;
k4=null;
System.gc();
System.out.println("Weak Hash Map :"+wm.toString());
System.out.println("Hash Map :"+hm.toString());
}
}
class Key{
private String key;
public Key(String key) {
this.key=key;
}
@Override
public boolean equals(Object obj) {
return this.key.equals((String)obj);
}
@Override
public int hashCode() {
return key.hashCode();
}
@Override
public String toString() {
return key;
}
}
Вывод: Weak Hash Map :{Java=Java, Hello=Hello, World=World, Programming=Programming}
Hash Map :{Programming=Programming, World=World, Java=Java, Hello=Hello}
Мой вопрос: почему WeakHashMap
не потеряет свои записи во втором примере кода даже после того, как ключи отбрасываются?
Ответы
Ответ 1
WeakHashMap
отбрасывает записи, когда ключ больше недоступен из живого кода. Поскольку HashMap
поддерживает жесткую ссылку на ключи, ключи по-прежнему доступны, а WeakHashMap
не WeakHashMap
записи.
Дело в том, что поведение связано со ссылками на ключевые объекты, а не со значением любой переменной, которая могла бы когда-то иметь ссылку на ключи.
Ответ 2
Объект должен быть отброшен везде, а затем WeakHashMap очищает этот объект. Как и WeakReference, его цель - запомнить объект, если он все еще используется. Без возникновения утечки памяти навсегда удерживая объект.
В вашем примере установите hm = null;
, чтобы увидеть волшебство очистки WeakHashMap.
Ответ 3
Вы установили null
на указатели k1,k2,k3,k4
но HashMap
и WeakHashMap
прежнему содержат ссылки на эти Keys
. А поскольку HashMap
содержит ссылку, фактические экземпляры ключей не удаляются GC. WeakHashMap
прежнему печатает их все.
Попробуйте запустить этот пример только с HashMap
->, даже если вы исключили эти ссылки, HashMap
все равно их сохранит.
Ответ 4
HashMap доминирует gc (сборщик мусора).
gc доминирует в WeakHashMap.
Несмотря на то, что мы устанавливаем значение null на k1, k2, k3, k4 gc, не удаляем из HashMap, где gc удаляет их все и предоставляет нам пустую карту для WeakHashMap, поэтому имя WeakHashMap
Ответ 5
Попробуй это -
class WeakHashMapExample {
public static void main(String[] args) {
Key k1 = new Key("Hello");
Key k2 = new Key("World");
Key k3 = new Key("Java");
Key k4 = new Key("Programming");
Map<Key, String> hm=new HashMap<Key, String>();
hm.put(k1, "Hello");
hm.put(k2, "World");
hm.put(k3, "Java");
hm.put(k4, "Programming");
k1=null;
k2=null;
k3=null;
k4=null;
System.gc();
System.out.println("Hash Map :"+hm);
System.out.println("Same thing with weakHash Map - ");
k1 = new Key("Hello");
k2 = new Key("World");
k3 = new Key("Java");
k4 = new Key("Programming");
Map<Key, String> wm = new WeakHashMap<Key, String>();
wm.put(k1, "Hello");
wm.put(k2, "World");
wm.put(k3, "Java");
wm.put(k4, "Programming");
k1=null;
k2=null;
k3=null;
k4=null;
System.gc();
System.out.println("Weak Hash Map :"+wm);
}
}
class Key{
private String key;
public Key(String key) {
this.key=key;
}
@Override
public boolean equals(Object obj) {
return this.key.equals((String)obj);
}
@Override
public int hashCode() {
return key.hashCode();
}
@Override
public String toString() {
return key;
}
public void finalize()
{
System.out.println("Finalize method is called");
}
}