2012-03-15 12 views
9

Estoy ejecutando una aplicación Java con un tamaño de almacenamiento máximo de 128 MB (-Xmx128M). Se está ejecutando para completar con éxito sin OutOfMemoryError, o cualquier otra excepción no controlada. Por lo tanto, supongo que su tamaño real de almacenamiento dinámico se mantuvo dentro del límite declarado de 128 MB.¿Por qué el uso total de la memoria de mi JVM es más de 30 veces mayor que su valor Xmx?

Sin embargo, al observar el proceso para esta aplicación Java, estoy viendo un uso total máximo de memoria de 4,188,548 KB (~ 4 GB). Este es un crecimiento de más de 30 veces el tamaño máximo controlado del montón. Aunque entiendo que este valor incluye memoria virtual asignada que puede ser significativamente mayor que la memoria física real utilizada, afecta los límites estrictos, como los impuestos por Sun Grid Engine, y por lo tanto es significativo.

¿Cómo es esto posible? Entiendo que la memoria total consumida por la JVM incluye bastante más que el tamaño del montón, pero no entiendo cómo podría necesitar varios GB de memoria extra más allá de lo que la aplicación realmente necesita para crear sus objetos y realizar su cálculo. .

Estoy usando Sun Java 1.6.0.31, en una distribución RHEL Linux de 64 bits.

+2

¿Está creando un número ilimitado de 'new Thread()' s? Cada hilo nativo que engendras tiene una pila de memoria que no es parte del montón de Java. – Affe

+0

¿Uso de memoria por qué medida? El espacio de direcciones asignado que no tiene ningún contenido real asignado probablemente no sea lo que más le importa; asegúrese de medir RSS, no VIRT. –

+0

@Affe No es un problema de enhebrado. La aplicación es de un solo subproceso. – jjcarver

Respuesta

4

Hay varios sumideros de memoria, además de la pila de Java controlado por -Xmx:

  • que las pilas de espacio
  • PermGen
  • directa ByteBuffers y cartografiado asigna ByteBuffer
  • memoria mediante el código/bibliotecas nativas

Sin conocer los detalles de su sistema, supongo, que algo utiliza maped ByteBuffers.

Pero podría profundizar en el problema examinando la salida del comando pmap. Enumera todas las regiones de memoria del proceso junto con los nombres de archivo a los que está asignada cualquier región (si las regiones son mapeadas, por supuesto).

+1

Es una gran sugerencia, aunque en la salida de pmap, desafortunadamente todas las regiones de memoria gravemente ofensivas tienen una columna de "Asignación" de "anon", p. '000000052d4c0000 7722240 0 0 rw --- [anon]' – jjcarver

+0

regiones 'anon' reducen la lista anterior a" libs nativas "y a" direccionar ByteBuffers ". –

Cuestiones relacionadas