Quantos threads uma Java VM suporta? Isso varia de acordo com o fornecedor? pelo sistema operacional? outros fatores?
fonte
Quantos threads uma Java VM suporta? Isso varia de acordo com o fornecedor? pelo sistema operacional? outros fatores?
Isso depende da CPU que você está usando, do sistema operacional, do que outros processos estão fazendo, do release de Java que você está usando e de outros fatores. Eu já vi um servidor Windows ter> 6500 Threads antes de desligar a máquina. A maioria dos threads não estava fazendo nada, é claro. Quando a máquina atingiu cerca de 6500 Threads (em Java), toda a máquina começou a ter problemas e se tornar instável.
Minha experiência mostra que Java (versões recentes) pode consumir felizmente tantos threads quanto o próprio computador pode hospedar sem problemas.
Obviamente, você precisa ter RAM suficiente e ter iniciado o Java com memória suficiente para fazer tudo o que os Threads estão fazendo e ter uma pilha para cada Thread. Qualquer máquina com uma CPU moderna (as mais recentes gerações de AMD ou Intel) e com 1 - 2 Gig de memória (dependendo do SO) pode facilmente suportar uma JVM com milhares de threads.
Se você precisar de uma resposta mais específica que essa, sua melhor aposta é criar um perfil.
Hum, muitos.
Existem vários parâmetros aqui. A VM específica, além disso, geralmente há parâmetros de tempo de execução na VM também. Isso é um pouco impulsionado pelo sistema operacional: que suporte o SO subjacente tem para os encadeamentos e quais limitações ele impõe a eles? Se a VM realmente usar encadeamentos no nível do sistema operacional, o bom e velho encadeamento vermelho / verde.
O que significa "suporte" é outra questão. Se você escreve um programa Java que é algo como
class DieLikeADog {
public static void main(String[] argv){
for(;;){
new Thread(new SomeRunaable).start();
}
}
}
(e não se queixe de pequenos detalhes de sintaxe, estou na minha primeira xícara de café), então você certamente deve esperar centenas ou milhares de threads em execução. Mas criar um Thread é relativamente caro e a sobrecarga do agendador pode ficar intensa; não está claro se você pode fazer com que esses threads façam algo útil.
Ok, não pude resistir. Aqui está o meu pequeno programa de teste, com alguns enfeites:
public class DieLikeADog {
private static Object s = new Object();
private static int count = 0;
public static void main(String[] argv){
for(;;){
new Thread(new Runnable(){
public void run(){
synchronized(s){
count += 1;
System.err.println("New thread #"+count);
}
for(;;){
try {
Thread.sleep(1000);
} catch (Exception e){
System.err.println(e);
}
}
}
}).start();
}
}
}
No OS / X 10.5.6 na Intel e Java 6 5 (veja comentários), aqui está o que eu recebi
Novo tópico # 2547 Novo tópico # 2548 Novo tópico # 2549 Não é possível criar o tópico: 5 Novo tópico # 2550 Exceção no encadeamento "main" java.lang.OutOfMemoryError: não é possível criar um novo encadeamento nativo em java.lang.Thread.start0 (método nativo) em java.lang.Thread.start (Thread.java:592) em DieLikeADog.main (DieLikeADog.java:6)
Depois de ler a postagem de Charlie Martin, fiquei curioso para saber se o tamanho da pilha faz alguma diferença no número de threads que você pode criar e fiquei totalmente impressionado com o resultado.
Usando o JDK 1.6.0_11 no Vista Home Premium SP1, executei o aplicativo de teste de Charlie com diferentes tamanhos de heap, entre 2 MB e 1024 MB.
Por exemplo, para criar um heap de 2 MB, eu chamaria a JVM com os argumentos -Xms2m -Xmx2m.
Aqui estão meus resultados:
Então, sim, o tamanho da pilha definitivamente importa. Mas a relação entre o tamanho do heap e a contagem máxima de encadeamentos é INVERSAMENTE proporcional.
O que é estranho.
fonte
Eu sei que esta pergunta é bastante antiga, mas só quero compartilhar minhas descobertas.
Meu laptop é capaz de lidar com programas que aparecem
25,000
threads e todos esses threads gravam alguns dados no banco de dados MySql em intervalos regulares de 2 segundos.Eu executei este programa com
10,000 threads
por30 minutes continuously
, em seguida, também o meu sistema estava estável e eu era capaz de fazer outras operações normais, como navegação, abrir, fechar outros programas, etc.Com
25,000 threads
sistemaslows down
mas ele permanece responsivo.Com o
50,000 threads
sistemastopped responding
instantaneamente e eu tive que reiniciar meu sistema manualmente.Os detalhes do meu sistema são os seguintes:
Antes de executar, defino o argumento jvm
-Xmx2048m
.Espero que ajude.
fonte
O máximo teórico absoluto é geralmente o espaço de endereço de usuário de um processo dividido pelo tamanho da pilha de threads (embora, na realidade, se toda a sua memória estiver reservada para pilhas de threads, você não terá um programa de trabalho ...).
Portanto, no Windows de 32 bits, por exemplo, em que cada processo tem um espaço de endereço de usuário de 2 GB, fornecendo a cada thread um tamanho de pilha de 128K, seria de esperar um máximo absoluto de 16384 threads (= 2 * 1024 * 1024/128). Na prática, acho que consigo inicializar cerca de 13.000 no XP.
Então, acho que você quer saber se (a) você pode gerenciar malabarismos com tantos threads em seu código e não fazer coisas obviamente tolas (como fazer com que todos esperem no mesmo objeto e chamar notifyAll () ...), e (b) se o sistema operacional pode. Em princípio, a resposta a (b) é "sim" se a resposta a (a) também é "sim".
Aliás, você pode especificar o tamanho da pilha no construtor do Thread ; você não precisa (e provavelmente não deveria) mexer nos parâmetros da VM para isso.
fonte
Lembro-me de ouvir uma conversa de Clojure em que ele executou um de seus aplicativos em uma máquina especializada em uma feira com milhares de núcleos (9000?), E carregou todos eles. Infelizmente, não consigo encontrar o link agora (ajuda?).
Com base nisso, acho seguro dizer que o hardware e seu código são os fatores limitantes, não a JVM.
fonte
Depois de brincar com a classe DieLikeACode de Charlie, parece que o tamanho da pilha de encadeamentos Java é uma grande parte de quantos encadeamentos você pode criar.
Por exemplo
Mas, Java tem a interface Executor . Eu usaria isso, você poderá enviar milhares de tarefas executáveis e solicitar ao Executor que processe essas tarefas com um número fixo de threads.
fonte
Runnable
/Callable
realmente precisar ser executado continuamente, como quando é necessário lidar com a comunicação. Mas é perfeito para consultas SQL.Pelo menos no Mac OS X 10.6 32bit, há um limite (2560) pelo sistema operacional. Verifique este encadeamento de fluxo de pilha .
fonte
O número máximo de threads depende do seguinte:
fonte
Informações adicionais para sistemas linux modernos (systemd).
Existem muitos recursos sobre isso de valores que podem precisar de ajustes (como Como aumentar o número máximo de encadeamentos da JVM (Linux de 64 bits) ); no entanto, um novo limite é imposto por meio do limite do sistema "TasksMax", que define pids.max no cgroup.
Para sessões de login, o UserTasksMax padrão é 33% do limite do kernel pids_max (geralmente 12.288) e pode ser substituído no /etc/systemd/logind.conf.
Para serviços, o padrão DefaultTasksMax é 15% do limite do kernel pids_max (geralmente 4.915). Você pode substituí-lo pelo serviço configurando TasksMax em "systemctl edit" ou atualizando DefaultTasksMax em /etc/systemd/system.conf
fonte
Ano de 2017 ... classe DieLikeADog.
Novo encadeamento # 92459 Exceção no encadeamento "main" java.lang.OutOfMemoryError: não é possível criar um novo encadeamento nativo
i7-7700 16gb ram
fonte
Você pode processar qualquer número de threads; não há limite. Executei o código a seguir enquanto assistia a um filme e usando o NetBeans, e ele funcionou corretamente / sem interromper a máquina. Eu acho que você pode manter ainda mais threads do que este programa.
fonte
main
lançarei umOutOfMemoryError
na minha máquina, dizendo que não é possível criar mais threads. Talvez @AnilPal, você não tenha notado isso. Sugiro incluir outra declaração de impressão nomain(..)
método, para ver claramente quando ele deixa de criar novos threads depois de gerar o erro.