2009-04-25 7 views
17

¿Cómo se optimiza el uso del tamaño de almacenamiento dinámico de una aplicación que tiene muchos (millones) de objetos de larga duración? (Caché grande, cargando un montón de registros de una base de datos)¿Cómo hace que la memoria de su aplicación Java sea eficiente?

  • utilizar el tipo de datos de la derecha
    • Evitar java.lang.String para representar otros tipos de datos
  • Evita duplicar objetos
    • Usar enumeraciones si los valores se conocen de antemano
    • Usar conjuntos de objetos
    • String.intern() (buena idea?)
  • Cargar/guardar sólo los objetos que necesita

Busco programación general o respuestas específicas Java. Sin un modificador de compilador original.

Editar:

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

Los casos de uso

  • carga un enorme archivo csv en la memoria (convertido en POJOs)
  • Uso de hibernación para recuperar millones de registros de una base de datos de

Hoja de vida de respuestas:

  • Utilice el diseño flyweight
  • Copiar al escribir
  • En lugar de cargar objetos 10M con 3 propiedades, ¿es más eficiente tener 3 matrices (u otra estructura de datos) del tamaño 10M? (Podría ser una molestia manipular datos, pero si realmente le falta la memoria ...)
+9

escribiendo su programa en el montaje ... :) –

+2

dudo que ayudaría ensamblador - tiempo de desarrollo sería significativamente más tiempo y no sería multiplataforma. ;) – Fortyrunner

+3

@Fortyrunner Sospecho que Desmond estaba haciendo una broma. –

Respuesta

17

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

  • Utilice un posible flyweight pattern donde .
  • Almacenamiento en caché para el disco. Hay numerous soluciones de caché para Java.
  • Existe un cierto debate sobre si String.intern es una buena idea. Ver here para una pregunta re. String.intern(), y la cantidad de debate sobre su idoneidad.
  • Haz uso de soft o weak referencias a los datos de la tienda que puedes recrear/volver a cargar a pedido.Consulte here para saber cómo usar referencias suaves con técnicas de almacenamiento en caché.

Saber más sobre el funcionamiento interno y la vida útil de los objetos que está almacenando daría lugar a una respuesta más detallada.

+0

Downvoted ¿por qué? –

20

Sugiero que utilice un generador de perfiles de memoria, vea dónde se está consumiendo la memoria y optimícela. Sin información cuantitativa, podrías terminar cambiando lo que no tiene ningún efecto o empeorar las cosas.

Puede ver cambiar la representación de sus datos, especialmente si sus objetos son pequeños. Por ejemplo, podría 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. p.ej. una tabla con 12 columnas y 10,000,000 filas podría usar 12 objetos (uno por columna) en lugar de 10 millones (uno por fila)

+0

Buen truco para minimizar el número de objetos. – Boune

+1

Acepto que un generador de perfiles de memoria es un buen punto de partida para alguien que no sabe qué instancias de clase toman toda la memoria. La pregunta es más, si sé de antemano tendré 10M pojo # 1 en la memoria, ¿cómo puedo minimizar el consumo de cada instancia? – Boune

11

Asegure una buena normalización de su modelo de objetos, no duplique los valores.

Ejem, y, si es sólo millones de objetos Creo que sólo iría para un decente poco VM 64 y una gran cantidad de memoria RAM;)

+1

Cuál es posiblemente la solución más rentable :-) –

+0

+1 - Eso está llegando al corazón del problema. – duffymo

+0

Gran respuesta. Usar cachés de datos y reducir registros y campos duplicados es un gran ahorro. – Fortyrunner

1

Quiero añadir algo al punto Pedro hizo alredy (puede No hagas ningún comentario sobre su respuesta :() siempre es mejor usar un generador de perfiles de memoria (ver java memory profiler) que ir por intuición. El 80% de las veces es una rutina que ignoramos tiene algún problema. También las clases de recolección son más propensas a la memoria fugas.

4

normal "perfiladores" no le ayudará mucho, ya que se necesita una visión general de todos los objetos "en vivo". usted necesita analizador de volcado del montón. recomiendo el Eclipse Memory analyzer.

Verifica si hay objetos duplicados, comenzando con Strings. Comprueba si puedes aplicar patrones como flightweight, copyonwrite, inicialización lenta (google será tu amigo).

2

Puede almacenar menos objetos en la memoria. :) Utilice un caché que se derrame en el disco o utilice Terracotta para agrupar su pila (que es virtual) permitiendo que las piezas no utilizadas se eliminen de la memoria y vuelvan a fallar transparentemente.

0

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

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

[lo que es una mejor estructura de datos]

  • Si se echa un vistazo a la fuente para las colecciones, se verá que si se restringe a sí mismo en la forma en que acceda a la colección, puede ahorrar espacio por elemento
  • La forma en que crece el asa de colección no es buena para grandes colecciones. Demasiada copia. Para colecciones grandes, necesita algún algoritmo basado en bloques, como btree.
+0

¿Cómo definirías mejores estructuras de datos? ¿Cómo implementarías eso? – Boune

0

Dedique un tiempo a conocer y ajustar el VM command line options, especialmente los relacionados con la recolección de basura. Si bien esto no cambiará la memoria utilizada por los objetos, puede tener un gran impacto en el rendimiento con las aplicaciones de memoria intensiva en máquinas con mucha RAM.

1

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

0
  1. Assign null valor a todo el variables que se no longer utiliza. Por lo tanto, make it available for Garbage collection.
  2. De-reference the collections una vez que el uso ha terminado, de lo contrario, GC no barrerá esos.
+1

No estoy de acuerdo con el ítem 1. Solo dejaría que el GC haga lo que se supone que debe hacer. Hay solo unos pocos casos (matrices, colecciones) donde esto podría ser útil, no todas las variables. http://stackoverflow.com/questions/449409/does-assigning-objects-to-null-in-java-impact-garbage-collection – Boune

Cuestiones relacionadas