Temos um servidor que executa vários aplicativos headless, como Java. Ele processa para transmitir dados, scripts python diários, etc. De tempos em tempos, alguns de nossos aplicativos ficam out of memory errors
.
O problema que temos é que o monitoramento mostra que há muita memória RAM. Aumentamos de 128 GB para 192 GB e não resolveu o problema. Nosso monitoramento faz uma leitura a cada 20 segundos e mostra a memória mínima disponível de 132 GB nos últimos 2 dias. Mas alguns aplicativos falharam com erros de falta de memória esta manhã. É possível obter OOM com bastante RAM disponível?
EDIT: Resposta às perguntas de David
- sim, os 192 GB são apenas a memória RAM alocada para o sistema operacional. É uma VM
- O monitoramento lerá ram livre/disponível para o sistema operacional, não temos nenhum monitoramento por processo
- A maioria dos processos java não especifica requisitos de memória na CLI (por exemplo, Xmx, etc.)
- A exceção é "Exceção no encadeamento "principal" java.lang.OutOfMemoryError: impossível criar novo encadeamento nativo"
Eu acrescentaria que vários processos falham ao mesmo tempo. Para mim, isso indicaria que não é um problema com o processo em si, mas algo a ver com o sistema. Alguns dos aplicativos que falham fazem a mesma coisa o dia todo, todos os dias, que é processar um fluxo de dados bastante consistente. Não é como se eles pudessem ser inundados com um grande número de solicitações.
Quando você diz "aumentamos de 128 GB para 192 GB e não resolveu o problema", o que você quer dizer? O espaço de heap da JVM? A VM do RHEL? Além disso, o que você quer dizer com "nosso monitoramento faz uma leitura?" Seu monitoramento está olhando para a memória heap Java ou para a memória do sistema?
Claro. A causa mais comum é que "muita RAM está disponível", mas não do tipo certo. por exemplo, você tem RAM no servidor, mas o processo Java não está configurado para usá-lo. Ou você tem RAM disponível no heap Java, mas o aplicativo Java precisa de memória de pilha em vez de memória de heap. Ou perm memória. Ou fora da memória heap.
Existem alguns outros casos extremos em que você pode obter um erro OOM mesmo com o acima, mas esses são muito raros. O mais provável é que você esteja adicionando o tipo errado de memória.
Se eu fosse depurar, meus primeiros passos seriam:
EDITAR EM RESPOSTA AO STACK TRACE:
Bem, parece que meu comentário "há alguns outros casos extremos" foi profético. Concordo com o comentário de Philipp Wendler de que esta é uma duplicata de https://stackoverflow.com/q/16789288/396730 . Na verdade, você não está ficando sem memória, está ficando sem threads.
Você pode procurar aqui: https://access.redhat.com/solutions/1420363 para saber como aumentar o número de threads (versão curta: atualização
/proc/sys/kernel/threads-max
). Mas, como é discutido na postagem Stack Overflow vinculada, você provavelmente precisará corrigir seu aplicativo em vez de apenas aumentar o limite. Qualquer aplicativo que use mais do que o número máximo padrão de encadeamentos provavelmente está vazando encadeamentos. (E se não estiverem, é definitivamente um desperdício de tópicos.) Especialmente se você disser que eles não estão sendo inundados com solicitações.Pensei em adicionar alguns dos comandos que usei para investigar o problema. Eu os adicionei ao cron para executar a cada minuto.