Смайлы Вкл.

В следующем примере кода, когда ключи установлены на нуль и вызывается 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"); 
} 

}