2012-06-11 11 views
12

Recientemente escribí una clase en la que descubrí que podía reducir el consumo de memoria de las instancias en ~ 10 bytes/elemento, pero solo a costa de hacer el código mucho más complejo. Esto aumentó el tamaño del archivo compilado .class por ~ 10 KB.¿Cómo calculo el consumo total de memoria permgen de una clase?

Supongo que la JVM tiene que cargar el archivo .class en la memoria, por lo que estos cambios no se amortizarán a menos que haya al menos 1000 elementos más o menos. Pero esa aritmética no funciona, a menos que los 10 KB adicionales en el archivo de clase sean , solo, el costo de la mayor complejidad del código.

This Oracle blog sugiere que hay una buena cantidad de memoria adicional consiguiendo consumido por la clase en el PermGen que no sólo se basa en el archivo .class - por ejemplo, sospecho que el código más complejo puede requerir más memoria para la optimización de metadatos .

Por lo tanto, esta pregunta tiene dos partes:

  • ¿Cómo puedo medir el consumo de memoria PermGen real de una clase en particular? ¿Ya sea en tiempo de ejecución con algunos instrumentos o con herramientas de creación de perfiles?
  • ¿Hay alguna manera de estimar el consumo de memoria permgen de la clase mientras la escribo? (Con some background knowledge, se puede estimar el consumo de memoria de las instancias de clase a medida que los va a escribir; me pregunto si se puede estimar el consumo de memoria PermGen de la propia clase.)

detalles similares para la máquina virtual Dalvik sería apreciado, pero estoy enfocado principalmente en OpenJDK y las otras JVM "mainstream".

+0

de perfiles podría ayudar –

+0

requisitos de memoria también dependerá de si HotSpot lo compila. El código JITed tiene su propio costo. –

+0

@JesseWilson: Esto es claramente cierto, pero ¿hay una buena manera de estimar ese costo? ¿Es solo el consumo del ensamblaje sin procesar, o hay mucha contabilidad adicional? –

Respuesta

4

¿Cómo puedo medir el consumo real de memoria permgen de una clase en particular? ¿Ya sea en tiempo de ejecución con algunos instrumentos o con herramientas de creación de perfiles?

Un enfoque podría cargar la clase de medir en un cargador de clases diferentes y utilizar jmap -permstat tal como se presenta en este blog entry.

Para cada objeto cargador de clases, se imprimen los siguientes detalles:

  1. La dirección del objeto cargador de clase - en la instantánea cuando se ejecutó la utilidad.
  2. El número de clases cargadas (definido por este cargador con el método (java.lang.ClassLoader.defineClass).
  3. El número aproximado de bytes consumidos por meta-datos para todas las clases cargadas por este cargador de clases.
  4. La dirección del cargador de clases principal (si corresponde).
  5. Indicación "en tiempo real" o "inactiva": indica si el objeto cargado será basura en el futuro.
  6. El nombre de clase de este cargador de clases.
+0

Oooooh. Voy a investigar esto. –

+0

@LouisWasserman: ¿se le ocurrió más información después de investigar? – dimo414

0

Esta es una respuesta a su segundo punto; No estoy seguro de lo útil que sería esto, pero encontré que las diapositivas de la presentación Building Memory-efficient Java Applications: Practices and Challenges son muy útiles para estimar el tamaño y la salud de varios objetos Java. Entra en muchos detalles cuando calcula tamaños para objetos en JVM de 32 bits y 64 bits, y también proporciona punteros para hacer que su objeto sea más eficiente con la memoria.

+0

De hecho, esa presentación es lo que me motivó a intentar escribir la implementación de elementos más compleja pero más eficiente desde el punto de vista de la memoria, pero ahora me pregunto si podría haberlo hecho. empeoró el problema ;) –

+0

@LouisWasserman No necesariamente peor, pero tal vez un poco más complicado. :) –

+0

Bueno ... si nunca hay más de 1000 elementos en las instancias en la memoria, parece probable que sea peor. –

Cuestiones relacionadas