A memória do processo Java é muito maior que os limites especificados

Eu pesquisei através da maioria dos métodos disponíveis para descobrir quanta memória um processo java realmente está usando. Até agora, posso dizer que sei que a memória total alocada pode ser uma ou mais das seguintes:

Memória acumulada (supostamente controlada pelo meu -XX: MaxHeapSize = 4096m)Memória permanente (supostamente controlada pelo meu -XX: MaxPermSize = 1024m)Cache de código reservado (supostamente controlado por meu -XX: ReservedCodeCacheSize = 256m)N de Threads * Tamanho do Encadeamento (supostamente controlado por my -XX: ThreadStackSize = 1024)

Mas os resultados são muito diferentes do que o linux me diz, com qualquer um dos métodos que encontrei disponíveis para obter o consumo de memória de um processo java.

No meu caso, é uma instância do Tomcat em execução em uma máquina Ubuntu 11.10 x86_64, JVM 1.6_u26 64 bits eps -ALcf | grep org.apache.catalina.startup.Bootstrap | wc -l me diz que eu tenho 145 threads ou processos em execução, todos ligados ao mesmo processo raiz (Tomcat).

Que tudo resumido deve me dar memória máxima total de (4096MB) + (1024MB) + (256MB) + 145 * (1024KB) = 5521MB. o quejmap -heap PID me diz o queManagementFactory.memoryMXBean.(heapMemoryUsage + nonHeapMemoryUsage).getCommitted() diz-me, e o valor teórico acima estão todos no par.

Agora para o lado do linux,top enmon ambos me dizem que ResidentMemory alocado por este processo é 5.8GB -> aproximadamente 5939,2MB. Mas eu também sei que isso é apenas parte da memória, a parte na memória RAM ao vivo. VIRT bytop e tamanho pornmon (ambos devem representar o mesmo) me diz que o processo é 7530MB (ou precisamente 7710952KB pornmon). Isso é diferente do esperado:2009MB acima do máximoe, de acordo com jmap e jstat, a alocação de memória não chegou ao seu pico (2048-OldSpace + 1534-Eden _ + _ Survivors).

top também me diz que a pilha de código é 36KB (justa, para a inicial catalina inicial), e pilha de dados é 7.3GB (representando o resto).

Essa instância do servidor tomcat é a única que está sendo executada nesta máquina e vem apresentando alguma instabilidade. Precisa ser reinicializado a cada três dias, porque a máquina tem 7647544k de RAM disponível e nenhuma troca (por motivos de desempenho). Eu fiz os cálculos para os limites, e esperando que o processo os acompanhasse eu vi que era uma boa margem de segurança para todos os outros serviços rodando na máquina (nenhum dos quais deveria se preocupar com o ssh e o próprio topo): 7468 - 5521 = 1947. Isso é quase demais para uma "margem de segurança".

Então, eu quero entender de onde está toda aquela memória sendo usada, e porque o limite não é obedecido. Se alguma informação estiver faltando, terei prazer em fornecer.

questionAnswers(2)

yourAnswerToTheQuestion