Pregunta

¿Cómo optimiza el uso del tamaño del montón de una aplicación que tiene mucho (millones) de objetos de larga vida? (Big Cache, cargando muchos registros de un DB)

  • Use el tipo de datos correcto
    • Evite java.lang.string para representar otros tipos de datos
  • Evite los objetos duplicados
    • Use enums si los valores se conocen de antemano
    • Use piscinas de objetos
    • String.intern () (¿buena idea?)
  • Cargar/mantener solo los objetos que necesita

Estoy buscando una programación general o respuestas específicas de Java. Sin interruptor de compilador funky.

Editar:

Optimice la representación de memoria de un POJO que puede aparecer millones de veces en el montón.

Casos de uso

  • Cargue un archivo CSV enorme en la memoria (convertido en POJOS)
  • Use Hibernate para recuperar millones de registros de una base de datos

Currículum de respuestas:

  • Use el patrón de peso mosca
  • Copiar en escrito
  • En lugar de cargar 10 m objetos con 3 propiedades, ¿es más eficiente tener 3 matrices (u otra estructura de datos) del tamaño de 10 m? (Podría ser un dolor para manipular datos, pero si realmente tiene la memoria de la memoria ...)
¿Fue útil?

Solución

No dices qué tipo de objetos estás buscando almacenar, por lo que es un poco difícil ofrecer consejos detallados. Sin embargo, algunos enfoques (no exclusivos), sin ningún orden en particular, son:

  • Utilizar una patrón de peso mosca donde sea posible.
  • Almacenamiento en caché al disco. Existennumeroso Soluciones de caché para Java.
  • Hay cierto debate sobre si String.Intern es una buena idea. Veraquí para una pregunta re. String.intern (), y la cantidad de debate sobre su idoneidad.
  • Hacer uso de suave o débilReferencias a los datos de la tienda que puede recrear/recargar bajo demanda. Veraquí para cómo usar referencias suaves con técnicas de almacenamiento en caché.

Saber más sobre las partes internas y la vida de los objetos que está almacenando daría como resultado una respuesta más detallada.

Otros consejos

Le sugiero que use un perfilador de memoria, vea dónde se consume la memoria y optimice eso. Sin información cuantitativa, podría terminar cambiando lo que no tiene efecto o realmente empeorar las cosas.

Puede considerar cambiar la representación de sus datos, ESP si sus objetos son pequeños. Por ejemplo, puede representar una tabla de datos como una serie de columnas con matrices de objetos para cada columna, en lugar de un objeto por fila. Esto puede ahorrar una cantidad significativa de sobrecarga para cada objeto si no necesita representar una fila individual. por ejemplo, una tabla con 12 columnas y 10,000,000 de filas podrían usar 12 objetos (uno por columna) en lugar de 10 millones (uno por fila)

Asegúrese de una buena normalización de su modelo de objeto, no duplique los valores.

Ejem, y, si son solo millones de objetos, creo que iría por una vm de 64 bits decente y mucha carnero;)

Los "perfiladores" normales no te ayudarán mucho, porque necesitas una descripción general de todos tus objetos "en vivo". Necesita el analizador de volcado de montón. Recomiendo el Analizador de memoria de eclipse.

Verifique los objetos duplicados, comenzando con cadenas. Compruebe si puede aplicar patrones como Flightweight, CopyOnWrite y Lazy Inicialización (Google será su amigo).

Eche un vistazo a esta presentación vinculada desde aquí. Establece el uso de la memoria de los objetos y primitivos Java comunes y lo ayuda a comprender hacia dónde va toda la memoria adicional.

Construir aplicaciones Java de consecuencia de memoria: prácticas y desafíos

Podrías almacenar menos objetos en la memoria. :) Use un caché que se derrame al disco o use terracota para agrupar su montón (que es virtual) que permite que las partes no utilizadas se eliminen de la memoria y sean criticadas de forma transparente.

Quiero agregar algo al punto que hizo Peter Alredy (no puedo comentar sobre su respuesta :() Siempre es mejor usar un perfilador de memoria (verificar Profiler de memoria de Java) que ir por la intuidad.80% del tiempo es rutina que ignoremos que tiene algún problema. También las clases de recolección son más propensas a las filtraciones de memoria.

Si tiene millones de enteros y flotadores, etc., vea si sus algoritmos permiten representar los datos en matrices de primitivas. Eso significa menos referencias y menor costo de CPU de cada recolección de basura.

Una elegante: mantenga la mayoría de los datos comprimidos en la RAM. Solo expanda el conjunto de trabajo actual. Si sus datos tienen una buena localidad que puede funcionar bien.

Utilice mejores estructuras de datos. Las colecciones estándar en Java son bastante intensivas en la memoria.

¿Qué es una mejor estructura de datos

  • Si observa la fuente de las colecciones, verá que si se restringe en cómo accede a la colección, puede ahorrar espacio por elemento.
  • La forma en que el manejo de la colección crece no es bueno para grandes colecciones. Demasiada copia. Para grandes colecciones, necesita un algoritmo basado en bloques, como Btree.

Pasar un tiempo familiarizarse y ajustar el Opciones de línea de comandos de VM, especialmente aquellos sobre recolección de basura. Si bien esto no cambiará la memoria utilizada por sus objetos, puede tener un gran impacto en el rendimiento con aplicaciones intensivas en memoria en máquinas con mucha RAM.

  1. Assign null valor a todos los variables que son no longer usó. De este modo make it available for Garbage collection.
  2. De-reference the collections Una vez que termina el uso, de lo contrario, GC no los barrerá.
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top