¿Cómo puedo eficiente de la caché de objetos en Java utilizando la memoria RAM disponible?

StackOverflow https://stackoverflow.com/questions/2158868

Pregunta

Necesito caché de objetos en Java usando una proporción de cualquiera que sea la RAM disponible.Soy consciente de que los otros han hecho esta pregunta, pero ninguna de las respuestas satisfacer mis necesidades.

Mis requisitos son:

  • Sencillo y ligero
  • No considerablemente más lento que el de un simple HashMap
  • Uso de la LRU, o algunos de la política de supresión que se aproxima a LRU

Traté de LinkedHashMap, sin embargo, se requiere especificar un número máximo de elementos, y no sé cuántos de los elementos que va a tomar para llenar la memoria RAM disponible (sus tamaños varían de forma significativa).

Mi enfoque actual es el uso de Google de la Colección de Mapeador de la siguiente manera:

Map<String, Object> cache = new MapMaker().softKeys().makeMap();

Esto parecía atractivo como debe eliminar automáticamente los elementos cuando se necesita más RAM, sin embargo, hay un problema grave:su comportamiento es llenar toda la memoria RAM disponible, momento en el que la GC comienza a thrash y todo el rendimiento de la aplicación se deteriora dramáticamente.

He oído hablar de cosas como EHCache, pero parece bastante peso pesado para lo que yo necesito, y no estoy seguro de si es lo suficientemente rápido para que mi aplicación (recordando que la solución no puede ser considerablemente más lento que un HashMap).

¿Fue útil?

Solución

Tengo requisitos similares para usted - simultaneidad (en 2 hexacore Cpu) y LRU o similar, y también trató de Guayaba MapMaker.He encontrado softValues() mucho más lento que weakValues(), pero ambos hizo que mi app extremadamente lenta cuando la memoria llena.

Traté de WeakHashMap y era menos problemático, por extraño que incluso más rápido que el uso de LinkedHashMap como LRU caché a través de su removeEldestEntry() método.

Pero por la forma más rápida para mí es ConcurrentLinkedHashMap lo que ha hecho que mi app 3-4 (!!) veces más rápido que cualquier otro caché he intentado.La alegría, después de días de frustración!Es al parecer ha incorporado en la Guayaba del Mapeador, pero la LRU función no está en la Guayaba r07 a cualquier precio.Espero que funcione para usted.

Otros consejos

He implementado cachés serval y es probable que sea tan difícil como la implementación de una nueva fuente de datos o subprocesos, mi recomendación es el uso jboss- caché o un otro conocido lib almacenamiento en caché. Por lo que dormir bien y sin problemas

  

he oído hablar de cosas como EHCache, pero parece bastante pesado-peso para lo que necesito, y no estoy seguro si es lo suficientemente rápido para mi aplicación (recordando que la solución no puede ser dramáticamente más lento de lo un HashMap).

Realmente no sé si se puede decir que EHCache es grueso y resistente. Al menos, yo no considero EHCache como tal, sobre todo cuando se utiliza una tienda memoria (que es respaldado por un extenso LinkedHashMap y es, por supuesto, el más rápido el almacenamiento en caché opción). Usted debe darle una oportunidad.

Creo MapMaker va a ser la única forma razonable para conseguir lo que estás pidiendo. Si "el GC comienza a agitarse y el rendimiento de toda la aplicación se deteriora dramáticamente", debe pasar algún tiempo de fraguado adecuadamente los distintos parámetros de ajuste. Este documento puede parecer un poco intimidante al principio, pero en realidad está escrito con mucha claridad y es una mina de oro de información útil acerca de GC:

http://java.sun.com/j2se/reference/whitepapers /memorymanagement_whitepaper.pdf

No sé si esto sería una solución sencilla, sobre todo en comparación con EHCache o similar, pero ¿has mirado en el Javolution biblioteca? No está diseñado para como tal, sino en el paquete javolution.context tienen un patrón de asignador que se puede reutilizar objetos sin la necesidad de recolección de basura. De esta manera mantener la creación de objetos y recolección de basura a un mínimo, una característica importante para la programación en tiempo real. Tal vez debería echar un vistazo y tratar de adaptarlo a su problema.

  

Esto pareció atractiva como debería   elementos de borrado automáticamente cuando se   necesita más memoria RAM, sin embargo hay una   grave problema: su comportamiento es   llenar toda la memoria RAM disponible

El uso de teclas de función simplemente permite que el recolector de basura para eliminar los objetos de la caché cuando ellos hacen referencia a ningún otro objeto (es decir, cuando la única cosa en referencia a la clave de caché es el propio caché). Esto no garantiza cualquier otro tipo de expulsión.

La mayoría de las soluciones que se encuentran características añadidas en la parte superior de las clases de Java mapa, incluyendo Ehcache.

¿Has mirado en la Commons-colecciones LRUMap

Tenga en cuenta que hay un tema abierto contra Map Maker para proporcionar funcionalidad LRU / MRU. Tal vez usted puede expresar su opinión allí también

El uso de la memoria caché existente, en lugar de almacenar WeakReference refererences objetos normales.

Si GC comienza a quedarse sin espacio libre, se darán a conocer los valores de los WeakReferences.

En el pasado he utilizado JCS . Puede configurar el configuración para tratar de satisfacer sus necesidades. No estoy seguro de si esto va a satisfacer todos sus requerimientos / necesidades, pero me pareció que estaba bastante potente cuando lo usé.

No se puede "elementos de borrado" sólo se puede detener a la referencia duro ellos y espera por el GC para limpiar ellos, a fin de ir adelante con Google Colecciones ...

No estoy al tanto de una manera fácil de averiguar el tamaño de un objeto en Java. Por lo tanto, no creo que encontrará una manera de limitar una estructura de datos por la cantidad de memoria RAM que está tomando.

Sobre la base de esta hipótesis, que está pegado con la limitación de que el número de objetos en caché. Me gustaría sugerir la realización de simulaciones de unos escenarios de uso de la vida real y la recolección de estadísticas sobre los tipos de objetos que van en la memoria caché. A continuación, se puede calcular el tamaño promedio estadístico, y el número de objetos que puede permitirse el lujo de caché. A pesar de que es sólo una aproximación de la cantidad de RAM que desea dedicar a la memoria caché, podría ser lo suficientemente bueno.

En cuanto a la aplicación de caché, en mi proyecto (una aplicación de rendimiento crítico) que estamos utilizando Ehcache, y personalmente no me parece que sea de peso pesado en absoluto.

En cualquier caso, ejecutar varias pruebas con varias configuraciones diferentes (en cuanto a tamaño, política de desalojo, etc.) y averiguar lo que funciona mejor para usted.

El almacenamiento en caché algo, SoftReference tal vez la mejor manera hasta ahora no me puedo imaginar.

O puede reinventar un objeto-piscina. Que cada objeto que no utiliza, no es necesario para destruirlo. Pero para guardar la CPU en lugar de guardar la memoria

Si se asume que desea que el caché de ser seguro para subprocesos, a continuación, usted debe examinar el ejemplo de caché en el libro de Brian Goetz "Java concurrencia en la práctica". No puedo recomendar lo suficiente.

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