Quantos threads uma Java VM suporta? Isso varia de acordo com o fornecedor? pelo sistema operacional? outros fatores?
Quantos threads uma Java VM suporta? Isso varia de acordo com o fornecedor? pelo sistema operacional? outros fatores?
Respostas:
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:
2 mb --> 5744 threads
4 mb --> 5743 threads
8 mb --> 5735 threads
12 mb --> 5724 threads
16 mb --> 5712 threads
24 mb --> 5687 threads
32 mb --> 5662 threads
48 mb --> 5610 threads
64 mb --> 5561 threads
96 mb --> 5457 threads
128 mb --> 5357 threads
192 mb --> 5190 threads
256 mb --> 5014 threads
384 mb --> 4606 threads
512 mb --> 4202 threads
768 mb --> 3388 threads
1024 mb --> 2583 threads
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.
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
sistema stopped responding
instantaneamente e eu tive que reiniciar meu sistema manualmente.
Os detalhes do meu sistema são os seguintes:
Processor : Intel core 2 duo 2.13 GHz
RAM : 4GB
OS : Windows 7 Home Premium
JDK Version : 1.6
Antes de executar, defino o argumento jvm -Xmx2048m
.
Espero que ajude.
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.
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.
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.
-Xss define o tamanho da pilha de threads java
Por exemplo
java -Xss100k DieLikeADog
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.
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 .
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
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
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.
class A extends Thread {
public void run() {
System.out.println("**************started***************");
for(double i = 0.0; i < 500000000000000000.0; i++) {
System.gc();
System.out.println(Thread.currentThread().getName());
}
System.out.println("************************finished********************************");
}
}
public class Manager {
public static void main(String[] args) {
for(double j = 0.0; j < 50000000000.0; j++) {
A a = new A();
a.start();
}
}
}
main
lançarei um OutOfMemoryError
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 no main(..)
método, para ver claramente quando ele deixa de criar novos threads depois de gerar o erro.