La memoria del proceso Java es mucho más grande que los límites especificados

He investigado a través de la mayoría de los métodos disponibles para averiguar cuánta memoria está usando realmente el proceso Java. Hasta ahora, puedo decir que sé que la memoria total asignada podría ser una o más de las siguientes:

Memoria del montón (supuestamente controlada por mi -XX: MaxHeapSize = 4096m)Memoria permanente (supuestamente controlada por mi -XX: MaxPermSize = 1024m)Caché de código reservado (supuestamente controlado por mi -XX: ReservedCodeCacheSize = 256m)N de subprocesos * Tamaño de subproceso (supuestamente controlado por mi -XX: ThreadStackSize = 1024)

Pero los resultados son muy diferentes de lo que Linux me dice, con cualquiera de los métodos que encontré disponibles para obtener el consumo de memoria de un proceso Java.

En mi caso, es una instancia de Tomcat que se ejecuta en una máquina Ubuntu 11.10 x86_64, JVM 1.6_u26 de 64 bits, yps -ALcf | grep org.apache.catalina.startup.Bootstrap | wc -l me dice que tengo 145 procesos o subprocesos en ejecución, todos vinculados al mismo proceso raíz (Tomcat).

Todo lo que se resume debe darme una memoria máxima total de (4096MB) + (1024MB) + (256MB) + 145 * (1024KB) = 5521MB. Quéjmap -heap PID me dice queManagementFactory.memoryMXBean.(heapMemoryUsage + nonHeapMemoryUsage).getCommitted() me dice, y el valor teórico anterior está en par.

Ahora al lado de linux,top ynmon ambos me dicen que ResidentMemory asignado por este proceso es 5.8GB -> aproximadamente 5939,2MB. Pero también sé que esto es solo una parte de la memoria, la parte de la memoria RAM en vivo. VIRT portop y tamaño pornmon (se supone que ambos representan el mismo) me dice que el proceso es 7530MB (o precisamente 7710952KB pornmon). Esto es demasiado diferente del máximo esperado:2009MB por encima del máximo, y de acuerdo con jmap y jstat, la asignación de memoria del montón ni siquiera alcanzó su punto máximo (2048-OldSpace + 1534-Eden _ + _ Survivors).

top También me dice que la pila de códigos es 36KB (aceptable, para el iniciador catalina inicial), y la pila de datos es de 7.3GB (que representa el resto).

Esta instancia del servidor Tomcat es la única que se ejecuta en esta máquina y ha estado observando cierta inestabilidad. Necesita reiniciarse cada tres días más o menos, porque la máquina tiene 7647544k de RAM disponibles y no hay intercambio (por razones de rendimiento). Hice los cálculos para los límites, y esperando que el proceso los siguiera, vi que era un margen de seguridad bastante bueno para los demás servicios que se ejecutan en la máquina (ninguno de los cuales debería molestar más que ssh y top): 7468 - 5521 = 1947. Eso es casi demasiado para un "margen de seguridad".

Entonces, quiero entender de dónde se usa toda esa memoria y por qué no se obedece el límite. Si falta alguna información, estaré encantado de proporcionarla.

Respuestas a la pregunta(2)

Su respuesta a la pregunta