Die Anleitung zu Java WeakHashMap
1. WeakHashMap
WeakHashMap ist eine Klasse ähnlich der Klasse HashMap, die alle hashing technique verwenden, um Daten zu speichern und abzurufen. Der Unterschied besteht darin, dass ein Objekt, das als Schlüssel von WeakHashMap angegeben ist, vom Garbage Collector (GC) aus dem Speicher entfernt werden kann, wenn es nicht mehr an einer anderen Stelle als GC verwendet wird. Sobald der Schlüssel von GC entfernt wurde, wird auch das entsprechende Mapping aus WeakHashMap entfernt.
Im normalen Gedanken ist ein Objekt, das irgendwo verwendet wird, nützlich und kann nicht aus dem Speicher entfernt werden. WeakHashMap ist jedoch speziell entwickelt und gilt als schwächer als GC, ein Objekt, dessen Schlüssel noch aus dem Speicher entfernt werden kann.
public class WeakHashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>
Die Klasse AnyObject wird an den Beispielen in diesem Artikel teilnehmen:
AnyObject.java
package org.o7planning.beans;
public class AnyObject {
private String s;
public AnyObject(String s) {
this.s = s;
}
public String getS() {
return s;
}
}
Sehen wir uns zuerst das folgende Beispiel an, dann analysieren wir, was passiert ist:
WeakHashMap_objectKey_ex1.java
package org.o7planning.weakhashmap.ex;
import java.util.WeakHashMap;
import org.o7planning.beans.AnyObject;
public class WeakHashMap_objectKey_ex1 {
public static void main(String[] args) throws InterruptedException {
// (1) Create a reference objK1 points to AnyObject("S1") object.
AnyObject objK1 = new AnyObject("S1");
AnyObject objK2 = new AnyObject("S2");
// Create WeakHashMap object:
WeakHashMap<AnyObject,Integer> map = new WeakHashMap<AnyObject,Integer>();
map.put(objK1, 1000);
map.put(objK2, 2000);
System.out.println(map);
// (2) Set reference objK1 to null.
objK1 = null;
// Garbage Collector is called
System.gc();
System.out.println("\n --- After Garbage Collector is called: --- \n");
Thread.sleep(3000);
System.out.println(map);
}
}
Output:
{org.o7planning.beans.AnyObject@1c4af82c=2000, org.o7planning.beans.AnyObject@5e91993f=1000}
--- After Garbage Collector is called: ---
{org.o7planning.beans.AnyObject@1c4af82c=2000}
(1) - Zuerst wird die Referenz objK1 erstellt und auf das Objekt AnyObject("S1") gezeigt, das ein Schlüssel von WeakHashMap ist.
(2) - Die Referenz objK1 zeigt auf einen Wert null. Zu diesem Zeitpunkt gibt es keine starken Verweise mehr, die auf das Objekt AnyObject("S1") verweisen. Obwohl es als Schlüssel von WeakHashMap verwendet wird, kann es dennoch von Garbage Collector entfernt werden. Da GC gilt stärker WeakHashMap.
Garbage Collector
Der Garbage Collector von Java arbeitet automatisch, um nicht verwendete Objekte aus dem Speicher zu entfernen. Sie können es mit der Methode System.gc() aktiv aufrufen, es gibt jedoch keine Garantie dafür, dass es sofort wirksam wird.
- Java Garbage Collector
Wenn wir bei der Änderung des obigen Beispiel wird WeakHashMap durch HashMap ersetzen, wird das Objekt AnyObject("S1") nicht von Garbage Collector entfernt. Denn HashMap gilt als stärker als Garbage Collector.
HashMap_objectKey_ex1.java
package org.o7planning.weakhashmap.ex;
import java.util.HashMap;
import org.o7planning.beans.AnyObject;
public class HashMap_objectKey_ex1 {
public static void main(String[] args) throws InterruptedException {
// (1) Create a reference objK1 points to AnyObject("S1") object.
AnyObject objK1 = new AnyObject("S1");
AnyObject objK2 = new AnyObject("S2");
// Create HashMap object:
HashMap<AnyObject,Integer> map = new HashMap<AnyObject,Integer>();
map.put(objK1, 1000);
map.put(objK2, 2000);
System.out.println(map);
// (2) Set reference objK1 to null.
objK1 = null;
// Garbage Collector is called
System.gc();
System.out.println("\n --- After Garbage Collector is called: --- \n");
Thread.sleep(3000);
System.out.println(map);
}
}
Output:
{org.o7planning.beans.AnyObject@1c4af82c=2000, org.o7planning.beans.AnyObject@5e91993f=1000}
--- After Garbage Collector is called: ---
{org.o7planning.beans.AnyObject@1c4af82c=2000, org.o7planning.beans.AnyObject@5e91993f=1000}
- HashMap
- LinkedHashMap
- TreeMap
- IdentityHashMap
- EnumMap
- ConcurrentSkipListMap
- ConcurrentHashMap
In diesem Artikel besprechen wir die verschiedenen Schlüsseltypen von WeakHashMap und wie GC sie behandelt.
No | Key Type | Example |
1 | Primitive | Integer aKey = 3;
String aKey = "aString"; |
2 | Object | newAnyObject();
newString("aString"); newInteger(3); |
2. Primitive Keys
Objekte, die aus primitiven Werten erstellt wurden, die keinen Operator "new" verwenden, werden von GC nicht entfernt, wenn sie als Schlüssel einer WeakHashMap verwendet werden
Primitive Keys
Integer key1 = 1000;
Double key2 = 2000.2;
String key3 = "SomeKey";
WeakHashMap_primitiveKey_ex1.java
package org.o7planning.weakhashmap.ex;
import java.util.WeakHashMap;
public class WeakHashMap_primitiveKey_ex1 {
public static void main(String[] args) throws InterruptedException {
// (1) Create a reference objK1 points to a primitive value.
Integer objK1 = 100;
Integer objK2 = 200;
// Create WeakHashMap object:
WeakHashMap<Integer, String> map = new WeakHashMap<Integer, String>();
map.put(objK1, "One Hundred");
map.put(objK2, "Two Hundred");
System.out.println(map);
// (2) Set reference objK1 to null.
objK1 = null;
// Garbage Collector is called
System.gc();
System.out.println("\n --- After Garbage Collector is called: --- \n");
Thread.sleep(5000);
System.out.println(map);
}
}
Output:
{200=Two Hundred, 100=One Hundred}
--- After Garbage Collector is called: ---
{200=Two Hundred, 100=One Hundred}
3. Object Keys
Objekte, die mit dem Operator "new" erstellt wurden, werden von GC aus dem Speicher entfernt, wenn kein starker Verweis darauf besteht, selbst wenn er als Schlüssel der WeakHashMap verwendet wird. Wie oben erwähnt, gilt GC als stärker als WeakHashMap.
Object Keys
AnyObject objK1 = new AnyObject("S1");
String objK2 = new String("S2");
Integer objK3 = new Integer(1000);
String objK4 = new String("S4");
Zum Beispiel:
WeakHashMap_objectKey_ex2.java
package org.o7planning.weakhashmap.ex;
import java.util.WeakHashMap;
import org.o7planning.beans.AnyObject;
public class WeakHashMap_objectKey_ex2 {
public static void main(String[] args) throws InterruptedException {
// (1) Create a reference objK1 points to String object.
AnyObject objK1 = new AnyObject("S1");
String objK2 = new String("S2");
Integer objK3 = new Integer(1000);
String objK4 = new String("S4");
// Create WeakHashMap object:
WeakHashMap<Object,Integer> map = new WeakHashMap<Object,Integer>();
map.put(objK1, 1000);
map.put(objK2, 2000);
map.put(objK3, 3000);
map.put(objK4, 4000);
System.out.println(map);
// (2) Set references objK1, objK2, objK3 to null.
objK1 = null;
objK2 = null;
objK3 = null;
// Garbage Collector is called
System.gc();
System.out.println("\n --- After Garbage Collector is called: --- \n");
Thread.sleep(3000);
System.out.println(map);
}
}
Output:
{S2=2000, org.o7planning.beans.AnyObject@5e91993f=1000, S4=4000, 1000=3000}
--- After Garbage Collector is called: ---
{S4=4000}
Objekte, die mit dem Operator "new" erstellt wurden, werden von GC aus dem Speicher entfernt, wenn das Programm mehr Speicher benötigt und keine starken Referenzen darauf verweisen. In diesem Fall müssen Sie die Methode System.gc() nicht aktiv aufrufen.
Im folgenden Beispiel versuchen wir, den Speicher zu füllen, indem wir kontinuierlich viele Objekte erstellen.
WeakHashMap_objectKey_ex3.java
package org.o7planning.weakhashmap.ex;
import java.util.WeakHashMap;
import org.o7planning.beans.AnyObject;
public class WeakHashMap_objectKey_ex3 {
public static void main(String[] args) throws InterruptedException {
// (1) Create a reference objK1 points to String object.
AnyObject objK1 = new AnyObject("S1");
String objK2 = new String("S2");
Integer objK3 = new Integer(1000);
String objK4 = new String("S4");
String objK5 = "S5"; // Primitive Key
// Create WeakHashMap object:
WeakHashMap<Object,Integer> map = new WeakHashMap<Object,Integer>();
map.put(objK1, 1000);
map.put(objK2, 2000);
map.put(objK3, 3000);
map.put(objK4, 4000);
map.put(objK5, 5000);
int ORIGIN_MAP_SIZE = map.size();
System.out.println(map);
int i = 0;
while(true) {
if(map.size() < ORIGIN_MAP_SIZE) {
System.out.println("WeakHashMap Size: " + map.size());
System.out.println(map);
break;
}
i++;
// (2) Make the memory full by creating lots of Strings
String s = new String("String" + i);
System.out.println("Create new String: " + s);
System.out.println(" >>> Now WeakHashMap size is: " + map.size());
}
}
}
Output:
{S2=2000, org.o7planning.beans.AnyObject@5e91993f=1000, S5=5000, S4=4000, 1000=3000}
Create new String: String1
....
Create new String: String347615
>>> Now WeakHashMap size is: 5
Create new String: String347616
>>> Now WeakHashMap size is: 5
Create new String: String347617
>>> Now WeakHashMap size is: 5
WeakHashMap Size: 1
{S5=5000}
4. Warum brauchen wir WeakHashMap?
Grundsätzlich ist WeakHashMap eine Lösung, um Speicher zu sparen, was nützlich ist, wenn Sie ein Objekt Map zum Speichern von Mapping für die Ihnen bekannten Schlüssel benötigen. Nicht mehr benötigte Schlüssel werden von GC automatisch entfernt.
Neben den oben genannten Eigenschaften hat WeakHashMap alle Eigenschaften einer regulären Map. Weitere Informationen zur Verwendung von Map finden Sie im folgenden Artikel
Mehr sehen:
Die Anleitungen Java Collections Framework
- Die Anleitung zu Java PriorityBlockingQueue
- Die Anleitung zu Java Collections Framework
- Die Anleitung zu Java SortedSet
- Die Anleitung zu Java List
- Die Anleitung zu Java Iterator
- Die Anleitung zu Java NavigableSet
- Die Anleitung zu Java ListIterator
- Die Anleitung zu Java ArrayList
- Die Anleitung zu Java CopyOnWriteArrayList
- Die Anleitung zu Java LinkedList
- Die Anleitung zu Java Set
- Die Anleitung zu Java TreeSet
- Die Anleitung zu Java CopyOnWriteArraySet
- Die Anleitung zu Java Queue
- Die Anleitung zu Java Deque
- Die Anleitung zu Java IdentityHashMap
- Die Anleitung zu Java WeakHashMap
- Die Anleitung zu Java Map
- Die Anleitung zu Java SortedMap
- Die Anleitung zu Java NavigableMap
- Die Anleitung zu Java HashMap
- Die Anleitung zu Java TreeMap
- Die Anleitung zu Java PriorityQueue
- Die Anleitung zu Java BlockingQueue
- Die Anleitung zu Java ArrayBlockingQueue
- Die Anleitung zu Java TransferQueue
Show More