Pergunta

Eu estou querendo saber, como é caro para ter muitos tópicos em estado de espera em java 1.6 x64.

Para ser mais específico, eu estou escrevendo aplicação que funciona através de muitos computadores e envia / recebe dados de um para outro. Eu me sinto mais confortável para ter thread separada para cada máquina conectada e tarefa, como 1) o envio de dados, 2) receber dados, 3) restabelecer ligação quando ele é descartado. Assim, dado que existem N nós em conjunto, cada máquina vai ter 3 fios para cada um dos N-1 vizinhos. Tipicamente, haverá máquinas 12, que trata de fios de comunicação 33.

A maioria desses tópicos será dormindo a maior parte do tempo, portanto, para fins de otimização eu poderia reduzir o número de threads e dar mais trabalho para cada um deles. Como por exemplo. restabelecer conexão é responsabilidade de receber fio. Ou enviar para todas as máquinas conectadas é feita por único segmento.

Assim há qualquer impacto perfomance significativa em ter muitos segmentos dormir?

Foi útil?

Solução

Na maioria dos casos, os recursos consumidos por um fio de dormir será o seu espaço de pilha. Utilizando um modelo 2-threads-per-ligação, que eu acho que é semelhante ao que você está descrevendo, é conhecido por causar grandes problemas de escalabilidade, por isso mesmo quando o número de conexões crescer grandes.

Eu estive nesta situação eu mesmo, e quando o número de ligações cresceu acima de 500 ligações (cerca de um milhar de threads), você tende a entrar em muitos casos em que você começa OutOfMemoryError, já que os tópicos pilha uso do espaço excede o quantidade máxima de memória para um único processo. Pelo menos no nosso caso, que estava em um Java em 32 bits do Windows mundo. Você pode ajustar as coisas e ficar um pouco mais, eu acho, mas no final não é apenas muito escalável desde que você desperdiça muita memória.

Se você precisa de um grande número de conexões, Java NIO (novo IO ou qualquer outro) é o caminho a percorrer, tornando possível para lidar com muitas conexões no mesmo segmento.

Dito isto, você não deve encontrar muito de um problema com menos de 100 threads em um servidor razoavelmente moderno, mesmo que seja provavelmente ainda um desperdício de recursos.

Outras dicas

Nós tivemos muito o mesmo problema antes de nós mudamos para NIO, por isso vou segundo Liedmans recomendação para ir com esse quadro. Você deve ser capaz de encontrar um tutorial, mas se você quiser os detalhes, eu posso recomendar Java NIO por Ron Hitchens.

Swithcing para NIO aumentou o número de conexões que poderia lidar com um monte, que foi muito crítico para nós.

Esta não escala muito bem. Ter um grande número de tópicos significa que a VM tem que gastar mais tempo contexto de comutação, e useage memória será maior devido a cada thread requerendo seu próprio espaço de pilha. Você seria melhor fora com um menor número de threads de processamento de forma encadeada, ou usar o pool de threads com técnicas Asychronous.

Muitos dos tópicos equivale a um monte de espaço de pilha, o que vai comer a sua memória -. Verificar suas configurações -Xss para o quanto, em seguida, fazer a matemática

E se você sempre tem que fazer um notifyAll () por alguma razão, então é claro que você está acordando cargas de tópicos extras -. Embora você pode não precisar fazer isso em sua arquitetura proposta

Eu não tenho certeza que você pode facilmente evitar ter um thread por soquete ouvir neste modelo (embora eu sei muito pouco sobre NIO - o que pode corrigir até mesmo essa questão), mas dê uma olhada no java.util.concurrent.Executor de interface e suas classes execução uma maneira decente para evitar ter muitos segmentos adicionais por perto. Na verdade, o ThreadPoolExecutor pode ser uma boa maneira de gerenciar seus segmentos de escuta também, para que você não gaste muito tempo criando e destruindo tópicos unneccessarily.

A partir dos testes que fiz em C, Lua e Python, você pode fazer o seu próprio sono ou função de espera com muito pouco linhas de códigos para fazer um laço leve simples. Use uma variável local com o tempo no futuro que você deseja alcançar e, em seguida, teste para o timestamp atual em um tempo loop. Se você estiver em um âmbito onde você trabalha com fps, fazer a função de espera run uma vez por quadro para economizar recursos. Quanto mais precisão que você precisa, considere usar o relógio em vez do timestamp, desde timestamp é limitado a segundos. Quanto mais linhas de código que você adiciona em uma função de espera, a menos precisas torna-se e quanto mais recursos que consome, embora nada menos de 10 linhas deve ser suficiente rápida.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top