java - logo - Diferencia entre "on-heap" y "off-heap"
Ehcache habla de memoria en montón y fuera de montón. ¿Cuál es la diferencia? ¿Qué argumentos de JVM se usan para configurarlos?
La JVM no sabe nada sobre la memoria off-heap. Ehcache implementa una memoria caché en disco así como una memoria caché en memoria.
La tienda on-heap se refiere a objetos que estarán presentes en el montón de Java (y también sujetos a GC). Por otro lado, la tienda off-heap se refiere a objetos (serializados) que son administrados por EHCache, pero almacenados fuera del montón (y que tampoco están sujetos a GC). A medida que la tienda fuera del montón continúa administrándose en la memoria, es un poco más lenta que la tienda on-heap, pero aún más rápida que la tienda de discos.
Los detalles internos que intervienen en la administración y el uso de la tienda off-heap no son muy evidentes en el enlace publicado en la pregunta, por lo que sería aconsejable consultar los detalles de Terracotta BigMemory , que se utiliza para administrar el fuera de disco. almacenar. BigMemory (la tienda fuera de pila) se utilizará para evitar la sobrecarga de GC en un montón que es de varios Megabytes o Gigabytes de gran tamaño. BigMemory utiliza el espacio de direcciones de memoria del proceso JVM, a través de ByteBuffers directos que no están sujetos a GC a diferencia de otros objetos nativos de Java.
No 100%; sin embargo, parece que el montón es un objeto o conjunto de espacio asignado (en la RAM) que está integrado en la funcionalidad del código, ya sea Java mismo o la funcionalidad más probable de ehcache en sí mismo, y el Ram fuera del montón es su propio sistema como bien; sin embargo, parece que esta es una magnitud más lenta, ya que no está organizada, lo que significa que no puede usar un montón (lo que significa un largo espacio de RAM), sino que utiliza diferentes espacios de direcciones, lo que hace que sea ligeramente menos eficiente.
Entonces, por supuesto, el siguiente nivel inferior es el espacio del disco duro.
No uso ehcache, por lo que puede que no quiera confiar en mí, pero eso es lo que reuní de su documentación.
de http://code.google.com/p/fast-serialization/wiki/QuickStartHeapOff
¿Qué es Heap-Offloading?
Por lo general, todos los objetos no temporales que asigna son gestionados por el recolector de basura de Java. Aunque la máquina virtual realiza un trabajo decente realizando la recolección de elementos no utilizados, en cierto punto, la máquina virtual debe hacer lo que se denomina "GC completo". Un GC completo implica escanear el Heap asignado completo, lo que significa que las pausas / ralentizaciones de GC son proporcionales al tamaño de un montón de aplicaciones. Así que no confíes en ninguna persona que te diga ''La memoria es barata''. En la memoria de Java, el consumo daña el rendimiento. Además, puede obtener pausas notables con tamaños de pila> 1 Gb. Esto puede ser desagradable si tienes algo en tiempo casi real, en un clúster o grilla un proceso java puede dejar de responder y ser eliminado del clúster.
Sin embargo, las aplicaciones de servidor de hoy (frecuentemente construidas encima de frameworks inflados ;-)) fácilmente requieren montones mucho más allá de 4Gb.
Una solución para estos requisitos de memoria es "descargar" partes de los objetos al montón no Java (directamente asignado desde el sistema operativo). Afortunadamente java.nio proporciona clases para asignar / leer y escribir directamente trozos de memoria "no administrados" (incluso archivos mapeados en memoria).
De modo que uno puede asignar grandes cantidades de memoria ''no administrada'' y usar esto para guardar objetos allí. Para guardar objetos arbitrarios en la memoria no administrada, la solución más viable es el uso de la serialización. Esto significa que la aplicación serializa los objetos en la memoria offheap, más adelante el objeto puede leerse utilizando la deserialización.
El tamaño de almacenamiento dinámico administrado por la máquina virtual de Java se puede mantener pequeño, por lo que las pausas de GC están en el milis, todo el mundo está contento, hecho.
Está claro, que el rendimiento de dicho buffer fuera de montón depende principalmente del rendimiento de la implementación de serialización. Buenas noticias: por alguna razón, la serialización FST es bastante rápida :-).
Ejemplos de uso de escenarios:
- Caché de sesión en una aplicación de servidor. Utilice un archivo mapeado de memoria para almacenar gigabytes de sesiones de usuario (inactivas). Una vez que el usuario inicia sesión en su aplicación, puede acceder rápidamente a los datos relacionados con el usuario sin tener que lidiar con una base de datos.
- Almacenamiento en caché de resultados computacionales (consultas, páginas html, ...) (solo aplicable si el cálculo es más lento que la deserialización del objeto resultante de c).
- persistencia muy simple y rápida usando archivos asignados de memoria
Editar: para algunos escenarios, uno puede elegir algoritmos de recolección de basura más sofisticados como ConcurrentMarkAndSweep o G1 para admitir montones más grandes (pero esto también tiene sus límites más allá de 16GB montones). También hay una JVM comercial con un GC (azul) "pausa" mejorado disponible.
El montón es el lugar en memoria donde viven sus objetos asignados dinámicamente. Si usaste new
entonces está en el montón. Eso es lo opuesto al espacio de pila, que es donde vive la pila de funciones. Si tiene una variable local, esa referencia está en la pila. El montón de Java está sujeto a la recolección de basura y los objetos se pueden usar directamente.
El almacenamiento fuera de almacenamiento de EHCache elimina su objeto habitual del montón, lo serializa y lo almacena como bytes en un trozo de memoria que EHCache administra. Es como almacenarlo en el disco, pero todavía está en la memoria RAM. Los objetos no son utilizables directamente en este estado, primero deben deserializarse. También no está sujeto a la recolección de basura.