2016-07-07 9 views
3

Ich habe Cache, mit WeakHashMap implementiert, wie folgt aus:Garbage Collector Arbeit mit 2 WeakHashMaps

private static WeakHashMap<Object, WeakReference<Object>> objects = new WeakHashMap<>(); 

ich eine Instanz der Klasse Stadt haben:

City c = new City(); 

ich diese Instanz auf meine Karte jetzt hinzufügen wie folgt:

objects.put(c, new WeakReference<Object>(c)); 

Laut WeakHashMap jvm Implementierung, wenn Schlüssel keine starken Referenzen zu haben es ist von der Karte gelöscht (in seiner Freizeit).
Wenn also mein Objekt 'c' nicht mehr im Programm verwendet wird, wird es aus der Objektkarte gelöscht.
So weit, so gut.

Aber was passiert, wenn ich zwei Karten habe?

private static WeakHashMap<Object, WeakReference<Object>> objects1 = new WeakHashMap<>(); 
private static WeakHashMap<Object, WeakReference<Object>> objects2 = new WeakHashMap<>(); 
City c = new City(); 
objects1.put(c, new WeakReference<Object>(c)); 
objects2.put(c, new WeakReference<Object>(c)); 

Wird GC in diesem Fall das Objekt 'c' sammeln?

+0

Wenn der Sensenmann entscheidet, ein Objekt zu ernten, ** alle ** Schwach Verweise auf sie wird angemessen zunichte gemacht. –

+0

warum wickeln Sie den Wert der HashMap in WeakReference ein? Sie sollten dies nicht tun, Sie könnten Nullwerte in diesem Fall haben –

+0

@EliaRohana Es kann nicht null sein, solange es woanders verwendet wird. – AndreyP

Antwort

3

Nehmen Sie ein Blatt Papier, zeichnen Sie ein Diagramm mit den Objekten als Vertices, Referenzen als Kanten.

Wenn Sie einen Pfad starker Kanten von einem GC-Stamm (z. B. statisches Feld oder lokale Variable im Stapel) zum Objekt in equestion nicht finden können, ist er nicht stark erreichbar und daher für GC geeignet.

+0

Also gibt es keine starken Kanten von WeakHashMap zu seinen Schlüsseln? – AndreyP

+1

Haben Sie die [WeakHashMap] (https://docs.oracle.com/javase/8/docs/api/java/util/WeakHashMap.html) Klasse javadocs gelesen? – the8472

+0

Die Schlüssel sind schwach, danke – AndreyP

0

Schwach ist schwach, es wird nicht stark, wenn es durch ein anderes schwaches verbunden wird.

Es wird Müll gesammelt werden, wenn keine andere starke Referenz. Kein Zweifel.

1

Sicher wird es es sammeln (wenn GC startet), weil es immer noch von WeakReference referenziert und nicht eine starke Referenz, egal wieviele WeakReferences es verweisen.

Sie können über WeakReference hier lesen: WeakReference

Hier ist ein Beispiel, es zu zeigen:

public class WeakHashMapExample { 

    //strongly reference key to prevent GC from collecting it 
    private static final Key stronglyRefKey1 = new Key(1); 

    public static void main(String[] args) throws InterruptedException { 

    WeakHashMap<Key, String> cache1 = new WeakHashMap<>(); 
    WeakHashMap<Key, String> cache2 = new WeakHashMap<>(); 

    //adding same keys 
    Key key2 = new Key(2); 
    cache1.put(stronglyRefKey1, "val 1"); 
    cache1.put(key2, "val 2"); 
    cache2.put(stronglyRefKey1, "val 1"); 
    cache2.put(key2, "val 2"); 
    key2 = null; // remove strong reference 

    //may or may not print Key(2) key, depends if GC starts at this point 
    System.out.println("cache1 = " + cache1); 
    System.out.println("cache2 = " + cache2); 

    //for GC to start so all weak reference should be cleared 
    System.gc(); 

    //after GC ha been ran, key(2) will be removed because its only referenced by weak reference of the WeakHashMap 
    System.out.println("cache1 = " + cache1); 
    System.out.println("cache2 = " + cache2); 
    } 

    private static class Key{ 
    int value; 

    private Key(int value) { 
     this.value = value; 
    } 

    @Override 
    public boolean equals(Object o) { 
     if (this == o) return true; 
     if (o == null || getClass() != o.getClass()) return false; 

     Key key = (Key) o; 

     if (value != key.value) return false; 

     return true; 
    } 

    @Override 
    public int hashCode() { 
     return value; 
    } 

    @Override 
    public String toString() { 
     return "Key{value=" + value +'}'; 
    } 
    } 
} 
+0

Im obigen Beispiel haben Sie 2 verschiedene Instanzen für Schlüssel (2) verwendet. Was, wenn es dieselbe Instanz war? Wenn WeakHashMap einen starken ref-Schlüssel hat, wird GC Key (2) nicht sammeln. – AndreyP

+0

i spielt keine Rolle, wenn die gleiche Instanz oder nicht, der Schlüssel, hier ist es nicht von einer starken Referenz verwiesen, so dass es für GC berechtigt ist. Ich habe den obigen Code bearbeitet, um dieselbe Instanz zu verwenden –