Frage

Ich wokiere Java mit einer großen (Millionen) Hashmap, die tatsächlich mit einer Kapazität von 10.000.000 und einem Lastfaktor von 0,75 gebaut wurde, und es wird verwendet, um einige Werte zu zwischenstrahlen

Da zwischengespeicherte Werte mit der Zeit nutzlos werden (nicht mehr zugegriffen), aber ich kann nutzlose nicht entfernen, während ich unterwegs den Cache vollständig leeren möchte, wenn sich seine Leistung verschlechtert. Wie kann ich entscheiden, wann es gut ist, es zu tun?

Zum Beispiel sollte ich mit 10 Millionen Kapazitäten und .75 es leeren, wenn es 7,5 Millionen Elemente erreicht? Weil ich verschiedene Schwellenwerte ausprobiert habe, aber ich hätte gerne eine analytische.

Ich habe bereits die Tatsache getestet, dass es ein Schub für die Perfomance ist, es zu verhindern, wenn es ziemlich voll ist (erste 2-3-Algorithmus-Iterationen nach dem Wischen, füllen Sie es einfach zurück, dann läuft es schneller als vor dem Wischtuch).

Bearbeiten: Zusätzliche Informationen

Die Hashmap hat lange Tasten und schweben Sie als Werte. Es enthält zwischengespeicherte Inhaltskorrelation, da es sich um ein Punktprodukt von Tag -Vektoren handelt, das ich ausspeichern wollte (um die Leistung zu steigern).

Im Grunde genommen tue ich also, a zu berechnen long Schlüssel unter Verwendung der Hashcodes des 2 Inhalts:

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;
}

und verwenden Sie es, um gespeicherte Werte abzurufen. Was passiert, ist, da es sich um einen hierarchischen Clustering -Inhalt handelt und ihre Korrelationswerte mit anderen Inhalten nicht mehr benötigt werden. Deshalb möchte ich den Hashmap von Zeit zu Zeit wischen, um Verschlechterung aufgrund nutzloser Werte darin zu vermeiden.

Verwendung einer WeakHashMap Wird unvorhersehbar auch Daten auslöschen, wenn sie noch benötigt werden. Ich habe keine Kontrolle darüber.

Vielen Dank

War es hilfreich?

Lösung

Warum nicht einen LRU -Cache verwenden? Aus Javas LinkedHashMap -Dokumentation:

Ein spezieller Konstruktor wird bereitgestellt, um eine verknüpfte Hash-Karte zu erstellen, deren Reihenfolge der Iteration die Reihenfolge ist, in der die Einträge zuletzt zugegriffen wurden, von dem am wenigsten zugänglich bis zum am meisten zugegriffenen (Zugriffsbestellung). Diese Art von Karte ist gut geeignet, um LRU-Caches zu bauen. Das Aufrufen der Put- oder Anholmethode führt zu einem Zugriff auf den entsprechenden Eintrag (vorausgesetzt, sie existiert nach Abschluss des Aufrufs). Die PUTALL-Methode generiert einen Eintragszugriff für jede Zuordnung in der angegebenen Karte, in der Reihenfolge, in der die Zuordnungen der Schlüsselwerte durch den Iterator der angegebenen MAP bereitgestellt werden. Keine anderen Methoden generieren Einstiegszugriffe. Insbesondere wirken sich Operationen auf Sammelansichten nicht auf die Reihenfolge der Iteration der Backing-Karte aus.

Im Grunde genommen löschen Sie von Zeit zu Zeit, wenn Ihre Karte zu groß wird, einfach die ersten X -Werte, die Ihnen der Iterator gibt.

Siehe Dokumentation für removeEldestEntry Um dies automatisch für Sie zu erledigen.

Hier ist Code, der demonstriert:

 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}
  }

Andere Tipps

Haben Sie untersucht WeapHashmaps ? Der Müllsammler kann bestimmen, wann man Dinge entfernen soll, und er kann einen akzeptablen Ersatz geben, anstatt selbst etwas zu kodieren.

Dieser Artikel hat mehr nützliche Informationen.

Möglicherweise möchten Sie Google -Sammlungen verwenden. ' Kartograph So erstellen Sie eine Karte mit weichen Referenzen und einer bestimmten Zeitüberschreitung.

Weiche Referenzen "werden nach Ermessen des Müllsammlers als Reaktion auf den Speicherbedarf geräumt."

Beispiel:

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

Sie können auch WeaPeys angeben, wenn Sie die Schlüssel wie die in einer schwachen Hasmap verhalten möchten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top