Existem algumas possibilidades dadas ao que você compartilhou, por exemplo:
- uma biblioteca JNI com vazamento ou
- um vazamento de criação de thread ou
- proxies de código dinâmico com vazamento (perm-gen leak),
mas só posso adivinhar porque você não forneceu nenhuma saída de log ou indique se a JVM estava lançando um OutOfMemoryException
(OOM) ou se alguma outra falha foi encontrada. Nem você mencionou o que o coletor de lixo estava em uso, embora as flags mostradas acima sejam as únicas opções da JVM em uso, é o coletor do CMS.
O primeiro passo é tornar as ações do coletor de lixo observáveis, adicionando estes sinalizadores:
-XX:+PrintTenuringDistribution
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+HeapDumpOnOutOfMemoryError
-Xloggc:/path/to/garbage.log
Se realmente é um OOM, você pode analisar o despejo de heap com VisualVM ou ferramenta semelhante. Eu também uso o VisualVM para monitorar a ação do GC in-situ via JMX. A visibilidade para os internos da JVM via pode ser ativada por esses flags da JVM:
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=4231
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
Recursos adicionais:
Atualizar
O log realmente ajuda. Obrigado. Esse log específico mostra que ficou sem memória física antes que ele pudesse aumentar o heap para o máximo configurado. Tentou malloc ~ 77M e havia apenas ~ 63M de esquerda:
Native memory allocation (malloc) failed to allocate 77873152 bytes for committing reserved memory.
..
/proc/meminfo: MemTotal: 1018724 kB MemFree: 63048 kB
Veja o que eu faria:
-
Reduza o heap para que ele "caiba" na máquina. Configure min e max heap para o mesmo valor você pode dizer se vai se encaixar imediatamente - não será iniciado se não se encaixa.
-
Você pode reduzir o tamanho da pilha Java (
-Xss
), mas essa coisa não parece estar fazendo um monte de tópicos para a poupança não será mais do que um Mb ou dois. Eu acho que o padrão para o Linux de 64 bits é de 256k. Reduza demais e comece a OOM nas alocações de pilha. -
Repita o teste.
-
Quando estiver sendo executado sob carga por um curto período, produza despejo de heap sob demanda para diagnóstico diferencial usando %código%.
-
Uma das duas coisas deve acontecer: (a) se houver um vazamento, ele falhará novamente, mas o tipo de OOM deve ser diferente, ou (b) não há um vazamento de tal forma que GC irá apenas trabalhe mais e você está feito. Como você tentou isso antes, o primeiro caso é provável, a menos que seu tamanho máximo reduzido também não se encaixe.
-
Se fizer OOM, compare os dois dumps para ver o que cresceu usando
jmap -dump:file=path_to_file <pid>
ou algum outro analisador de heap.
Boa sorte!