2013-09-23 6 views
6

Im folgenden Codebeispiel, wenn Schlüssel auf Null gesetzt sind und System.gc() aufgerufen wird, verliert der WeakHashMap alle Zuordnungen und wird geleert.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 :{}

Wenn WeakHashMap auf null zusammen mit HashMap und Tasten eingestellt verwendet wird, wird die WeakHashMap nicht seine Schlüssel-Wert-Zuordnungen verlieren.

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; 
} 

} 

Ausgang: Weak Hash Map :{Java=Java, Hello=Hello, World=World, Programming=Programming} Hash Map :{Programming=Programming, World=World, Java=Java, Hello=Hello}

Meine Frage ist, warum nicht die WeakHashMap seine Einträge in dem zweiten Codebeispiel verlieren, selbst nachdem die Schlüssel weggeworfen werden?

Antwort

11

Ein WeakHashMap verwirft Einträge, wenn der Schlüssel nicht mehr vom Live-Code aus erreichbar ist. Da die HashMap einen harten Verweis auf die Schlüssel unterhält, sind die Schlüssel immer noch erreichbar und die WeakHashMap verwirft die Einträge nicht.

Der Punkt ist, dass das Verhalten mit Verweisen auf die Schlüsselobjekte zu tun hat, nicht auf den Wert einer Variablen, die zu einem Zeitpunkt möglicherweise einen Verweis auf die Schlüssel hatte.

+0

Ich habe noch nie an Variablen gedacht, die nur einen Zeiger enthalten, das ist sehr informativ zu wissen, danke! – xorinzor

2

Ein Objekt muss überall sonst verworfen werden, und dann löscht die WeakHashMap dieses Objekt. Wie eine WeakReference hat sie den Zweck, sich an ein Objekt zu erinnern, wenn es noch benutzt wird. Ohne ein Speicherleck zu verursachen, das für immer ein Objekt hält.

In Ihrem Beispiel Set hm = null;, um die Magie der WeakHashMap Aufräumen zu sehen.

+0

ja, Einstellung 'hm = null' vor 'System.gc()' löscht das WHM. Danke, ich habe es. – Nishant

3

Sie eingestellt haben null auf Zeiger k1,k2,k3,k4 aber HashMap und WeakHashMap noch enthält Verweise auf diese Keys. Und becouse HashMap enthält Referenz, tatsächliche Instanzen der Schlüssel werden nicht von GC gelöscht. WeakHashMap druckt immer noch alle von ihnen.

Versuchen Sie dieses Beispiel nur laufen mit HashMap -> auch, dass youve diese refereneces HashMap wird sie noch draußen bleiben auf Null gesetzt.

0

HashMap dominiert GC (Garbage Collector).

gc dominiert WeakHashMap.

Auch wenn wir auf k1 null gesetzt, k2, k3, k4 gc wird nicht von HashMap entfernen, wo als gc entfernt sie alle und bietet uns leer Karte für WeakHashMap daher der Name WeakHashMap