2009-05-14 7 views
4

Existe-t-il un LinkedHashMap basé sur softreference en Java? Si non, quelqu'un a-t-il reçu un extrait de code que je peux probablement réutiliser? Je promets de le référencer correctement.Référence Soft LinkedHashMap en Java?

Merci.

+4

Si vous prévoyez de faire cela pour un cache sensible à la mémoire, sachez que la mémoire disponible est un très mauvais moyen de tout régler. Dans un environnement de grande taille, vous pouvez conserver des objets périmés pendant très longtemps, ce qui ralentit le fonctionnement global. Les caches basés sur le temps et la taille sont bien meilleurs. Cela peut aussi vous intéresser: http://www.kdgregory.com/index.php?page=java.refobj – kdgregory

Répondre

3

La meilleure idée que j'ai vu pour cela est l'emballage LinkedHashMap de sorte que tout ce que vous put en elle est un WeakReference. MISE À JOUR: Il suffit de parcourir la source de WeakHashMap et la façon dont il gère tout faire un WeakReference tout en jouant encore sympa avec les génériques est solide. Voici la signature de la classe de base utilise:

private static class Entry<K,V> extends WeakReference<Object> implements Map.Entry<K,V> 

Je suggère la navigation the source plus en profondeur d'autres idées de mise en œuvre.

MISE À JOUR 2: kdgregory soulève un bon point dans son commentaire - tout ce que je vous suggère c'est de vous assurer que les références du Map n'empêcheront pas le référent d'être récupéré. Vous devez toujours nettoyer les références mortes manuellement.

+3

Cela ne fonctionne pas vraiment, car les références ne disparaîtront jamais, elles seront juste effacées. Et vous finirez avec une carte pleine de références mortes. Si vous regardez de plus près le code de WeakHashMap, vous verrez qu'il purge paresseusement les références mortes (je crois en utilisant une file d'attente de référence). – kdgregory

6

WeakHashMap ne conserve pas l'ordre d'insertion. Il ne peut donc pas être considéré comme un remplacement direct de LinkedHashMap. De plus, l'entrée de la carte n'est libérée que lorsque la clé n'est plus accessible. Ce qui n'est peut-être pas ce que vous cherchez.

Si ce que vous cherchez est une mémoire cache conviviale, voici une implémentation naïve que vous pourriez utiliser.

package be.citobi.oneshot; 

import java.lang.ref.SoftReference; 
import java.util.LinkedHashMap; 

public class SoftLinkedCache<K, V> 
{ 
    private static final long serialVersionUID = -4585400640420886743L; 

    private final LinkedHashMap<K, SoftReference<V>> map; 

    public SoftLinkedCache(final int cacheSize) 
    { 
     if (cacheSize < 1) 
      throw new IllegalArgumentException("cache size must be greater than 0"); 

     map = new LinkedHashMap<K, SoftReference<V>>() 
     { 
      private static final long serialVersionUID = 5857390063785416719L; 

      @Override 
      protected boolean removeEldestEntry(java.util.Map.Entry<K, SoftReference<V>> eldest) 
      { 
       return size() > cacheSize; 
      } 
     }; 
    } 

    public synchronized V put(K key, V value) 
    { 
     SoftReference<V> previousValueReference = map.put(key, new SoftReference<V>(value)); 
     return previousValueReference != null ? previousValueReference.get() : null; 
    } 

    public synchronized V get(K key) 
    { 
     SoftReference<V> valueReference = map.get(key); 
     return valueReference != null ? valueReference.get() : null; 
    } 
} 
2

jetez un oeil à this post. Il montre comment implémenter un SoftHashMap ...

+2

Apache Shiro a déjà une implémentation de cette méthode (avec approbation) et l'a sous licence sous Apache v2. Il est emballé avec Apache [Shiro] [1]. Vous pouvez trouver la documentation [ici] [2] et le code source [ici] [3]. [1]: http://en.wikipedia.org/wiki/Apache_Shiro [2]: http://shiro.apache.org/static/1.1.0/apidocs/ [3]: http: //shiro.apache.org/static/1.1.0/apidocs/src-html/org/apache/shiro/util/SoftHashMap.html – DallinDyer

Questions connexes