Question

Je suis woking sur Java avec un grand (en millions) hashmap qui est en fait construit avec une capacité de 10.000.000 et un facteur de charge de .75 et il est utilisé pour mettre en cache certaines valeurs

puisque les valeurs mises en cache deviennent inutiles avec le temps (pas plus accédé) mais je ne peux pas enlever les inutiles tandis que sur la façon dont je voudrais tout vider le cache lorsque ses performances commence à se dégrader. Comment puis-je décider quand il est bon de le faire?

Par exemple, avec 10 millions capacité et .75 dois-je vider quand il atteint 7,5 millions d'éléments? Parce que j'ai essayé différentes valeurs de seuil, mais je voudrais avoir une une analyse.

Je l'ai déjà testé le fait que emping quand il est tout à fait complet est un coup de pouce pour perfomance (2-3 premières itérations de l'algorithme après la lingette suffit de remplir le récupérer, il commence à courir plus vite que avant la lingette)

EDIT: INFO ADDITIONNELLE

Le hashmap a longtemps que les clés et flottent comme des valeurs. Il contient corrélation mises en cache des contenus, car il est un produit scalaire de vecteurs d'étiquette que je voulais les mettre en cache (pour augmenter les performances).

Donc, fondamentalement, ce que je fais est de calculer une clé long en utilisant les codes de hachage des 2 contenus:

static private long computeKey(Object o1, Object o2)
{
    int h1 = o1.hashCode();
    int h2 = o2.hashCode();

    if (h1 < h2)
    {
        int swap = h1;
        h1 = h2;
        h2 = swap;
    }

    return ((long)h1) << 32 | h2;
}

et l'utiliser pour récupérer les valeurs stockées. Ce qui se passe est que, puisque c'est un contenu classification hiérarchique sont fusionnés et leurs valeurs de corrélation avec d'autres contenus ne sont pas nécessaires plus .. voilà pourquoi je veux essuyer la hashmap de temps en temps, pour éviter la dégradation due à des valeurs inutiles à l'intérieur.

L'utilisation d'un WeakHashMap va effacer les données imprévisiblement aussi quand ils sont encore nécessaires .. Je n'ai pas le contrôle.

Merci

Était-ce utile?

La solution

Pourquoi ne pas utiliser un cache LRU? D'après la documentation LinkedHashMap Java:

  

Un constructeur spécial est prévu pour   créer une carte de hachage liée dont l'ordre   de l'itération est l'ordre dans lequel son   les entrées du dernier accès, de   moins récemment accédé à   plus récemment (accès ordre). Cette   genre de carte est bien adapté à la construction   caches LRU. Invoquer le put ou obtenir   procédé conduit à un accès à la   entrée correspondant (en supposant que   existe après l'invocation   battant). Procédé putAll   génère un accès d'entrée pour chaque   cartographier sur la carte spécifiée, dans la   ordonner que les correspondances clé-valeur sont   fournie par l'entrée de la carte spécifiée   ensemble iterator. Aucune autre méthode   générer entrée accède. Dans   en particulier, les opérations sur   collecte-vues ne touchent pas la   ordre de l'itération du plan de support.

Donc, fondamentalement, tous les temps en temps que votre carte est trop grande, il suffit de supprimer les premières valeurs de x que le iterator vous donne.

Voir la documentation pour removeEldestEntry que cela soit fait automatiquement pour vous.

Voici le code qui démontre:

 public static void main(String[] args) {
    class CacheMap extends LinkedHashMap{
      private int maxCapacity;
      public CacheMap(int initialCapacity, int maxCapacity) {
        super(initialCapacity, 0.75f, true);
        this.maxCapacity = maxCapacity;
      }

      @Override
      protected boolean removeEldestEntry(Map.Entry eldest) {
        return size()>maxCapacity;
      }
    }

    int[] popular = {1,2,3,4,5};
    CacheMap myCache = new CacheMap(5, 10);
    for (int i=0; i<100; i++){
      myCache.put(i,i);
      for (int p : popular) {
        myCache.get(p);
      }
    }

    System.out.println(myCache.toString()); 
    //{95=95, 96=96, 97=97, 98=98, 99=99, 1=1, 2=2, 3=3, 4=4, 5=5}
  }

Autres conseils

Avez-vous enquêté WeakHashMaps ? Le garbage collector peut déterminer quand enlever des choses et il peut vous donner un substitut acceptable plutôt que de coder quelque chose vous-même.

Cet article contient des informations plus utiles.

Vous pouvez utiliser Google Collections' pour faire MapMaker une carte avec des références douces et un délai d'attente spécifique.

Références douces « sont effacées à la discrétion du collecteur des ordures en réponse à la demande de mémoire ».

Exemple:

ConcurrentMap<Long, ValueTypeHere> cacheMap = new MapMaker()
    .concurrencyLevel(32)
    .softValues()
    .expiration(30, TimeUnit.MINUTES)
    .makeMap();

Vous pouvez également spécifier weakKeys si vous voulez faire ses clés agissent comme ceux dans un WeakHashMap.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top