[resolvido] Número excessivo de threads, -Xss, socket, list, performance? channel, nio

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");
			}
		}
	}

} 

. desculpa .

Ola

Se esse é realmente o caso, sem duvida a abordagem nao deve ser sincrona. Voce deve usar a api do java.nio e evitar ao maximo o padrao thread-per-connection, utilizando o Channel do ServerSocket. Registre esse Channel num Selector e receba todos os eventos em uma unica thread. Coloque isso dentro de um event-loop e, para cada evento, vai utilizano uma thread (e em vez de abrir nova thread, use um ThreadPoolExecutor da factory do Executors.

opa, desculpa a demora,

consegui resolver o problema como vc falou…

o unico limite foi o numero de portas permitidas para conexão TCP/IP na SO…
que foi resolvido alterando diretamente a regkey.

deixarei em anexo a fonte do teste que fiz com as classes, caso seja útil para alguem no futuro ^^

Obrigado Paulo.