devstory

Le Tutoriel de Java WeakHashMap

  1. WeakHashMap
  2. Primitive Keys
  3. Object Keys
  4. Pourquoi a-t-on besoin de WeakHashMap?

1. WeakHashMap

WeakHashMap est une classe similaire à la classe HashMap, qui utilise toutes une technique de hachage (hashing technique) pour stocker et récupérer des données. La différence est que si un objet est spécifié comme la clé de WeakHashMap, il peut être supprimé de la mémoire par Garbage Collector (GC) s'il n'est plus utilisé ailleurs plus fort que GC. Une fois la clé supprimée par GC, le mappage correspondant est également supprimé de WeakHashMap.
Dans la plupart des cas, si un objet est utilisé quelque part, il est utile et ne peut pas être supprimé de la mémoire. Cependant, WeakHashMap est spécialement conçue et est considérée comme plus faible que GC, un objet dont la clé peut toujours être supprimée de la mémoire.
public class WeakHashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>
La classe AnyObject sera parue dans les exemples de cet article:
AnyObject.java
package org.o7planning.beans;

public class AnyObject  {
    private String s;
    public AnyObject(String s)  {
        this.s = s;
    }
    public String getS() {
        return s;
    }
}
D'abord, observer l'exemple ci-dessous et analyser ce qui s'est passé:
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) - Tout d'abord, la référence objK1 est créée et pointée vers l'objet AnyObject("S1"), qui est une clé de WeakHashMap.
(2) La référence -ObjK1 pointe vers une valeur null. À ce moment-là, il n'y a plus de références fortes qui pointent vers l'objet AnyObject("S1"). Bien qu'il soit utilisé comme clé de WeakHashMap, il est toujours considéré comme éligible pour être supprimé par Garbage Collector. Puisque GC est considéré comme plus fort que WeakHashMap.
Garbage Collector
Le Garbage Collector de Java fonctionne automatiquement pour supprimer les objets inutilisés de la mémoire. Vous pouvez l'appeler activement avec la méthode System.gc(), mais rien ne garantit qu'elle sera effective immédiatement.
  • Java Garbage Collector
En modifiant l'exemple ci-dessus, si on remplace WeakHashMap par HashMap, l'objet AnyObject("S1") ne sera pas supprimé par Garbage Collector. Puisque HashMap est considérée comme plus forte que 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}
Dans cet article, on examinera des différents types de clés de WeakHashMap et de la façon dont GC les traite.
No
Key Type
Example
1
Primitive
Integer aKey = 3;
String aKey = "aString";
2
Object
newAnyObject();
newString("aString");
newInteger(3);

2. Primitive Keys

Les objets créés à partir de valeurs primitives qui n'utilisent pas l'opérateur "new" ne seront pas supprimés par GC s'il est utilisé comme clé d'une WeakHashMap.
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

Les objets créés avec l'opérateur "new" seront supprimés de la mémoire par GC s'il n'y a pas de référence forte qui pointe vers lui, même s'il est utilisé comme clé de la WeakHashMap. Comme mentionné ci-dessus, GC est considéré comme plus fort que WeakHashMap.
Object Keys
AnyObject objK1 = new AnyObject("S1");
String objK2 = new String("S2");
Integer objK3 = new Integer(1000);
String objK4 = new String("S4");
Par exemple:
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}
Les objets créés par l'opérateur "new" seront supprimés de la mémoire par GC si le programme a besoin de plus de mémoire et s'il n'y a pas de références fortes pointant vers lui. Dans ce cas, vous n'avez pas besoin d'appeler activement la méthode System.gc().
Dans l'exemple ci-dessou, on essaie de remplir la mémoire en créant continuellement plusieurs objets.
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. Pourquoi a-t-on besoin de WeakHashMap?

En règle générale, WeakHashMap est une solution permettant d'économiser de la mémoire, ce qui est utile si vous avez besoin d'un objet Map afin de stocker les mappages pour les clés que vous connaissez. Les clés qui ne sont plus utiles sont automatiquement supprimées par GC.
En plus des caractéristiques mentionnées ci-dessus, WeakHashMap dispose de toutes les caractéristiques d'une Map ordinaire. Vous pouvez en savoir plus sur l'utilisation de Map dans l'article ci-dessous :
Voir plus: