Hello folks.
Preciso de uma sugestão de implementação com relação a milhares de threads, list e performance.
Em determinado projeto, é necessário o aplicativo aguentar a conexão por Socket de até 10000 clientes (sim… até 10 mil) , o que vai gerar esse mesmo numero de threads simultaneas.
Fiz alguns testes de performance com a classe Thread ‘nativa’, JVM sem args, e o Java aguenta ± 5 mil threads.
Decidi adicionar alguns argumentos na JVM
Fiz o mesmo teste com -Xms256m -Xmx256m -Xss2048
rodou 22379 threads antes de dar exception
Com muita lógica e inteligência, decidi aumentar a memoria de 256mb para 1gb.
-Xms1024m -Xmx1024m -Xss2048
rodou 11259 threads…
agora a duvida, pq foi menor o numero de threads se tinha mais memoria?
o que faz aumentar o numero de threads e baixando o -Xss, e nao aumentando o -Xms e -Xmx
não entendo se isso tem algo haver com o SO (win XP), pois li que no linux o numero de threads que aguenta é maior (nao deu pra testar aqui)
na verdade eu nem sei se seria viavel um -Xss baixo, sendo que cada thread vai possuir algumas variaveis relacionadas a leitura do seu respectivo Socket (em TCP).
e agora, devo abordar a solução de passar os sockets para UDP, para que não tenha uma conexão/thread para cada client?
(o que provavelmente vai fazer aumentar o processamento necessario por mensagem/tratamento/erro, como descreve o segundo problema abaixo)
seguindo este problema, existe tb o tratamento de milhares de mensagens por segundo que devem ser executadas na ordem de chegada, e em uma unica thread para evitar erros de validação com o BD.
Fiz um teste executando aquelas 5000 threads adicionando tudo em uma ArrayList
cada thread adicionando 1 tarefa a cada 500ms, (não vai ser tão exagerado, mas temos que testar na pior situação possivel né) …
enquanto isso uma outra thread do servidor lia e processava o index 0, e removia o mesmo da lista, sendo assim um loop infinito lendo o index 0…
aguentou tranquilamente, considerando que o processo não fazia nada alem de umas contas idiotas…
porem com processos um pouco mais pesados e o dobro de threads, provavelmente ele nao vai aguentar.
Existe algum meio de acessar/inserir/remover mais rapido que uma array list?
o acesso/remover será sempre do Index 0… e o inserir sempre no último Index.
Qualquer dica ou sugestão para melhorar performance será bem-vinda.
Obrigado.
Edit:
Segue o código fonte do teste de Threads:
public class ThreadTest {
public static void main(String[] pArgs) throws Exception {
try {
while (true) {
new TestThread().start();
}
} catch ( OutOfMemoryError e ) {
System.out.println(TestThread.CREATE_COUNT );
System.exit(-1);
}
}
static class TestThread extends Thread {
private static int CREATE_COUNT = 0;
public TestThread() {
CREATE_COUNT++;
}
public void run() {
try {
sleep(Integer.MAX_VALUE );
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
}
}
}