2013-09-23 3 views
6

В следующем примере кода, когда ключи установлены в нуль и вызывается System.gc(), WeakHashMap теряет все сопоставления и освобождается.WeakHashMap vs HashMap

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 и ключи устанавливаются в нуль, то 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 теряет свои записи во втором примере кода, даже после того, как ключи выбрасывают?

ответ

11

A WeakHashMap отбрасывает записи, когда ключ больше не может быть достигнут с живого кода. Поскольку HashMap поддерживает жесткую ссылку на клавиши, ключи все еще доступны, а WeakHashMap не отбрасывает записи.

Дело в том, что поведение связано со ссылками на ключевые объекты, а не на значение любой переменной, которая могла бы иметь когда-то ссылку на ключи.

+0

Я даже не думал о переменных, поскольку просто содержит указатель, это очень информативно, чтобы знать, спасибо! – xorinzor

2

Объект объект должен быть отброшен везде, а затем WeakHashMap очищает этот объект. Как и WeakReference, его цель - запомнить объект, если он все еще используется. Не вызывая утечки памяти навсегда, удерживая объект.

В вашем примере установите hm = null;, чтобы увидеть магию очистки WeakHashMap.

+0

да, установка 'гм = null' перед 'System.gc()' выполняет очистку WHM. Спасибо, я понял. – Nishant

3

Вы установили null на указатели k1,k2,k3,k4 но HashMap и WeakHashMap все еще содержит ссылки на те Keys. И becouse HashMap содержит referenece, фактические экземпляры ключей не удаляются GC. WeakHashMap все еще печатает все.

Попробуйте запустить этот пример только с HashMap -> даже если вы отклонили эти реферины HashMap все равно сохраните их.

0

HashMap доминирует gc (сборщик мусора).

gc доминирует WeakHashMap.

Даже если мы ставим нуль на k1, k2, k3, k4 дс обыкновение удалить из HashMap, где, как дс удаляет их и дает нам пустую карту для WeakHashMap отсюда и название WeakHashMap

Смежные вопросы