Pregunta

Estoy woking en Java con un HashMap grandes (millones) que en realidad está construido con una capacidad de 10.000.000 y un factor de carga de 0,75 y se utiliza para almacenar en caché algunos valores

ya que los valores almacenados en caché se vuelven inútiles con el tiempo (no accedí a más), pero no puedo quitar los inútiles, mientras que en el camino me gustaría completamente vacía la caché cuando su rendimiento comienza a degradarse. ¿Cómo puedo decidir cuando es bueno hacerlo?

Por ejemplo, con capacidad de 10 millones y 0,75 debo vaciarlo cuando alcanza 7,5 millones de elementos? Porque he intentado varios valores de umbral, pero me gustaría tener uno analítica.

Ya he probado el hecho de que emping cuando es bastante completo es un impulso para la perfomance de (primeras 23 iteraciones del algoritmo después de la toallita sólo tiene que rellenar de nuevo, entonces empieza a correr más rápido que antes la toallita)

EDIT: INFORMACIÓN ADICIONAL

El HashMap tiene siempre y cuando las llaves y flotar como valores. Contiene correlación en caché de contenido, ya que es un producto escalar de vectores de etiquetas que quería caché ellos (para aumentar el rendimiento).

Así que básicamente lo que hago es para calcular una clave long utilizando los hashcodes de los contenidos 2:

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

y utilizarlo para recuperar los valores almacenados. Lo que ocurre es que, dado que se trata de una agrupación jerárquica contenidos se fusionaron y sus valores de correlación con otros contenidos no son necesarios más .. es por eso que quiero para limpiar el HashMap de vez en cuando, para evitar la degradación debido a los valores inútiles en su interior.

El uso de un WeakHashMap será impredecible eliminar datos también cuando todavía son necesarios .. no tengo control sobre él.

Gracias

¿Fue útil?

Solución

¿Por qué no utilizar un caché LRU? A partir de la documentación LinkedHashMap de Java:

  

Un constructor especial aquí suministrada   crear un mapa hash ligado cuyo orden   de iteración es el orden en que su   las entradas se accedió por última, desde   menos recientemente visitada a   más recientemente (acceso en el orden). Esta   tipo de mapa es muy adecuado para la construcción   cachés LRU. La invocación de la opción de venta o conseguir   método da como resultado un acceso a la   entrada correspondiente (suponiendo que   existe después de la invocación   completa). El método putAll   genera un acceso de entrada para cada   mapeo en el mapa especificado, en el   orden de que las asignaciones de valores clave son   proporcionado por la entrada del mapa especificado   conjunto iterador. No hay otros métodos   generar accesos de entrada. En   particulares, las operaciones en   recogida de vistas no afectan a la   orden de iteración de la correlación de respaldo.

Así que, básicamente, de vez en cuando como su mapa se hace demasiado grande, basta con borrar los primeros valores de x que el iterador le da.

Consulte la documentación de removeEldestEntry que esto se haga de forma automática.

Este es el código que se muestra:

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

Otros consejos

¿Ha investigado WeakHashMaps ? El recolector de basura puede determinar cuándo se debe quitar cosas y se le puede dar un sustituto aceptable en lugar de la codificación algo por sí mismo.

Este artículo tiene la información más útil.

Es posible que desee utilizar Google Colecciones Map Maker para hacer un mapa con referencias suaves y un tiempo de espera específico.

Las referencias blandas "se borran a discreción del recolector de basura en respuesta a la demanda de memoria."

Ejemplo:

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

También puede especificar weakKeys si usted quiere hacer sus teclas actúan como los de un WeakHashMap.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top