Estamos recebendo "java.lang.OutOfMemoryError : unable to create new native Thread
"na VM de 8 GB de RAM após 32k threads (ps -eLF | grep -c java)
No entanto "top" and "free -m" shows 50% free memory available
,. O JDk é de 64 bits e tentou com o HotSpot e o JRockit.Server com o Linux 2.6.18
Também tentamos OS stack size (ulimit -s)
ajustar e os limites máximos de processo (ulimit -u), limit.conf aumentam, mas todos em vão.
Também tentamos quase todas as combinações possíveis de tamanho de pilha, mantendo-a baixa, alta etc.
O script que usamos para executar o aplicativo é
/opt/jrockit-jdk1.6/bin/java -Xms512m -Xmx512m -Xss128k -jar JavaNatSimulator.jar /opt/tools/jnatclients/natSimulator.properties
Obrigado pela resposta.
Tentamos editar o arquivo /etc/security/limits.conf e ulimit, mas ainda assim
[root@jboss02 ~]# ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 72192
max locked memory (kbytes, -l) 32
max memory size (kbytes, -m) unlimited
open files (-n) 65535
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 10240
cpu time (seconds, -t) unlimited
max user processes (-u) 72192
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
java
out-of-memory
Deepak Tewani
fonte
fonte
ExecutorService
).Respostas:
Esse não é um problema de memória, embora o nome da exceção o sugira, mas um problema de recurso do sistema operacional. Você está ficando sem threads nativos, ou seja, quantos threads o sistema operacional permitirá que sua JVM use.
Esse é um problema incomum, porque você raramente precisa disso. Você tem muitas criações incondicionais de encadeamentos onde os encadeamentos devem, mas não terminam?
Você pode reescrever o uso de Callable / Runnables sob o controle de um Executor, se possível. Existem muitos executores padrão com vários comportamentos que seu código pode controlar facilmente.
(Existem muitas razões pelas quais o número de encadeamentos é limitado, mas eles variam de sistema operacional para sistema operacional)
fonte
Encontrei o mesmo problema durante o teste de carga, o motivo é que a JVM não conseguiu criar um novo encadeamento Java. Abaixo está o código fonte da JVM
No meu caso, o Jboss está criando muitos threads, para atender à solicitação, mas todos os threads estão bloqueados. Por esse motivo, a JVM se esgota com threads e também com memória (cada thread contém memória, que não é liberada, porque cada thread está bloqueado).
Analisados os despejos de encadeamento java observados, quase os encadeamentos de 61K são bloqueados por um de nosso método, o que está causando esse problema. Abaixo está a parte do despejo de segmento
fonte
É provável que seu sistema operacional não permita o número de threads que você está tentando criar ou esteja atingindo algum limite na JVM. Especialmente se for um número redondo como 32k, um limite de um tipo ou outro é provavelmente o culpado.
Tem certeza de que realmente precisa de threads de 32k? A maioria das linguagens modernas tem algum tipo de suporte para conjuntos de threads reutilizáveis - eu tenho certeza que o Java também tem algo em vigor (como o
ExecutorService
usuário Jesper mencionou). Talvez você possa solicitar threads desse pool, em vez de criar manualmente novos.fonte
Eu recomendaria também verificar o tamanho da pilha de threads e ver se você criou mais threads. O tamanho da pilha de encadeamentos padrão para o JRockit 1.5 / 1.6 é 1 MB para a VM de 64 bits no sistema operacional Linux. Os threads de 32K exigirão uma quantidade significativa de memória física e virtual para atender a esse requisito.
Tente reduzir o tamanho da pilha para 512 KB como ponto de partida e veja se isso ajuda a criar mais threads para seu aplicativo. Também recomendo explorar o dimensionamento horizontal, por exemplo, dividindo o processamento do aplicativo em mais máquinas físicas ou virtuais.
Ao usar uma VM de 64 bits, o limite verdadeiro dependerá da disponibilidade da memória física e virtual do SO e dos parâmetros de ajuste do SO, como ulimitc. Também recomendo o seguinte artigo como referência:
OutOfMemoryError: não é possível criar um novo encadeamento nativo - Problema desmistificado
fonte
Se a jvm for iniciada via systemd, pode haver um limite de maxTasks por processo (as tarefas realmente significam encadeamentos) em alguns sistemas operacionais Linux.
Você pode verificar isso executando "status do serviço" e verifique se há um limite de maxTasks. Se houver, você pode removê-lo editando /etc/systemd/system.conf, adicionando uma configuração: DefaultTasksMax = infinity
fonte
Eu tive o mesmo problema devido a processos fantasmas que não apareciam ao usar o top no bash. Isso impediu a JVM de gerar mais encadeamentos.
Para mim, ele resolveu ao listar todos os processos java com jps (basta executar
jps
no seu shell) e os matou separadamente, usando okill -9 pid
comando bash para cada processo fantasma.Isso pode ajudar em alguns cenários.
fonte
Você tem a chance de enfrentar
java.lang.OutOfMemoryError: Unable to create new native thread
sempre que a JVM solicitar um novo encadeamento no sistema operacional. Sempre que o sistema operacional subjacente não puder alocar um novo encadeamento nativo, esse OutOfMemoryError será lançado. O limite exato para encadeamentos nativos depende muito da plataforma, portanto, é recomendável descobrir esses limites executando um teste semelhante ao exemplo de link abaixo. Mas, em geral, a situação causadorajava.lang.OutOfMemoryError: Unable to create new native thread
passa pelas seguintes fases:Referência: https://plumbr.eu/outofmemoryerror/unable-to-create-new-native-thread
fonte
Para descobrir quais processos estão criando threads, tente:
Eu normalmente redireciono a saída para um arquivo e analiso o arquivo offline (a contagem de threads para cada processo é conforme o esperado ou não)
fonte
Se sua tarefa estiver falhando devido ao OutOfMemmory nos nós, você poderá alterar seu número de mapas e redutores máximos e a JVM optar por cada um. mapred.child.java.opts (o padrão é 200Xmx) geralmente precisa ser aumentado com base no hardware específico do seu nó de dados.
Este link pode ser útil ... pls check
fonte
sua configuração do JBoss tem alguns problemas, /opt/jrockit-jdk1.6/bin/java -Xms512m -Xmx512m Xms e Xmx estão limitando o uso de memória do JBoss ao valor configurado, portanto, a partir de 8Gb, o servidor tem apenas 512M + alguns extras para seu próprio objetivo, aumente esse número, lembre-se de deixar alguns gratuitos para o sistema operacional e outras coisas em execução no site e talvez você o faça funcionar, apesar do código desagradável. Corrigir o código também seria bom, se você puder.
fonte
Este erro pode aparecer devido aos seguintes motivos:
Não há espaço na memória para acomodar novos threads.
O número de threads excede o limite do sistema operacional.
Duvido que o número de threads tenha excedido o limite para o processo java
Então, provavelmente, o problema é por causa da memória. Um ponto a considerar é
A solução possível é reduzir a memória heap ou aumentar o tamanho geral da ram
fonte
Eu tive esse mesmo problema e acabou sendo um uso inadequado de uma API java. Eu estava inicializando um construtor em um método de processamento em lote que não deveria ser inicializado mais de uma vez.
Basicamente, eu estava fazendo algo como:
quando eu deveria ter feito isso:
fonte
Antes de tudo, eu não culparia tanto o OS / VM ... mas o desenvolvedor que escreveu o código que cria tantos Threads . Basicamente, em algum lugar do seu código (ou de terceiros), muitos threads são criados sem controle .
Revise cuidadosamente o código de rastreamento de pilha e controle o número de threads que são criados. Normalmente, seu aplicativo não deve precisar de uma grande quantidade de threads, se houver, é um problema diferente.
fonte