Por que a equipe da LMAX projetou o LMAX Disruptor em Java, mas todos os seus pontos de design para minimizar o uso do GC? Se alguém não deseja que o GC seja executado, por que usar um idioma de coleta de lixo?
Suas otimizações, o nível de conhecimento de hardware e o pensamento que colocam são impressionantes, mas por que Java?
Eu não sou contra Java ou qualquer coisa, mas por que uma linguagem GC? Por que não usar algo como D ou qualquer outro idioma sem o GC, mas permite um código eficiente? Será que a equipe está mais familiarizada com Java ou o Java possui alguma vantagem exclusiva que não estou vendo?
Digamos que eles o desenvolvam usando D com gerenciamento manual de memória, qual seria a diferença? Eles teriam que pensar em um nível baixo (o que já são), mas podem obter o melhor desempenho do sistema, pois é nativo.
Respostas:
Porque existe uma enorme diferença entre otimizar o desempenho e desativar completamente uma segurança
Ao reduzir o número de GC, sua estrutura é mais responsiva e pode ser executada (presumivelmente) mais rapidamente. Agora, otimizar o coletor de lixo não significa que eles nunca façam uma coleta de lixo. Significa apenas que eles fazem isso com menos frequência e, quando o fazem, é executado muito rápido. Esse tipo de otimização inclui:
Quando você diminui o desempenho, geralmente ajusta algum "hot spot" muito específico, ignorando o código que não é executado com frequência. Se você fizer isso em Java, poderá deixar o coletor de lixo ainda cuidar dos cantos escuros (já que não fará muita diferença) enquanto otimiza com muito cuidado a área que executa em um loop apertado. Assim, você pode escolher onde otimizar e onde não, e assim concentrar seu esforço no que interessa.
Agora, se você desativar completamente a coleta de lixo, não poderá escolher. Você deve descartar manualmente todos os objetos, sempre. Esse método é chamado no máximo uma vez por dia? Em Java, você pode deixar, pois seu impacto no desempenho é insignificante (pode ser bom permitir que um GC completo ocorra todos os meses). No C ++, você ainda está vazando recursos, portanto, você deve cuidar mesmo desse método obscuro. Portanto, você deve pagar o preço pelo gerenciamento de recursos em cada parte única do seu aplicativo, enquanto em Java você pode se concentrar.
Mas piora.
E se você tiver um bug, digamos no canto escuro do seu aplicativo, que só é acessado na segunda-feira na lua cheia? Java tem uma forte garantia de segurança. Há pouco ou nenhum "comportamento indefinido". Se você usar algo errado, uma exceção será lançada, o programa será interrompido e nenhuma corrupção de dados ocorrerá. Então você tem certeza de que nada de errado pode acontecer sem você perceber.
Mas em algo como D, você pode ter um acesso incorreto ao ponteiro ou um estouro de buffer e pode corromper sua memória, mas seu programa não saberá (você desligou a segurança, lembra-se?) E continuará funcionando com as informações incorretas. dados, faça algumas coisas bastante desagradáveis e corrompa seus dados, e você não sabe, e à medida que mais corrupção acontece, seus dados ficam cada vez mais errados e, de repente, eles se quebram, e estavam em um aplicativo essencial à vida, e ocorreu algum erro no cálculo de um foguete, e por isso não funciona, o foguete explode e alguém morre, e sua empresa está na primeira página de todos os jornais e seu chefe aponta o dedo para você dizendo "Você está o engenheiro que sugeriu que usamos o D para otimizar o desempenho, por que você não pensou em segurança?". E a culpa é sua. Você matou essas pessoas com sua tentativa tola de desempenho.
OK, ok, na maioria das vezes é muito menos dramático do que isso. Mas mesmo um aplicativo essencial para os negócios ou apenas um aplicativo de GPS ou, digamos, um site de assistência médica do governo pode gerar algumas conseqüências bastante negativas se você tiver bugs. Usar uma linguagem que os impeça completamente ou que falhem rapidamente quando eles acontecem geralmente é uma idéia muito boa.
Há um custo para desativar uma segurança. Ser nativo nem sempre faz sentido. Às vezes, é muito mais simples e seguro otimizar um idioma um pouco seguro, para buscar um idioma em que você possa se dar muito bem. Em muitos casos, a correção e a segurança superam os poucos nanossegundos que você teria eliminado ao eliminar completamente o GC. Disruptor pode ser usado nessas situações, então acho que o LMAX-Exchange fez a ligação certa.
Mas e D em particular? Você tem um GC, se quiser, para os cantos escuros, e o subconjunto SafeD (que eu não conhecia antes da edição) remove o comportamento indefinido (se você se lembrar de usá-lo!).
Bem, nesse caso, é uma simples questão de maturidade. O ecossistema Java está cheio de ferramentas bem escritas e bibliotecas maduras (melhor para o desenvolvimento). Muito mais desenvolvedores conhecem Java do que D (melhor para manutenção). Buscar uma linguagem nova e não tão popular para algo tão crítico quanto um aplicativo financeiro não seria uma boa idéia. Com uma linguagem menos conhecida, se você tiver um problema, poucos podem ajudá-lo e as bibliotecas que você encontra tendem a apresentar mais erros, pois foram expostas a menos pessoas.
Portanto, meu último argumento ainda é válido: se você deseja evitar problemas com conseqüências terríveis, fique com opções seguras. Neste ponto da vida de D, seus clientes são as pequenas empresas prontas para assumir riscos loucos. Se um problema pode custar milhões, é melhor ficar mais longe na curva dos sinos da inovação .
fonte
Parece que o motivo pelo qual ele foi escrito em Java é que eles possuem conhecimento interno em Java e provavelmente foi escrito (embora ainda esteja em desenvolvimento ativo) antes que o C ++ agisse junto com o C ++ 0x / 11.
Seu código é realmente apenas Java pelo nome, eles usam sun.misc.Unsafe bastante que meio que derrota o ponto de Java e a segurança é supostamente concedida. Eu escrevi uma porta C ++ do Disruptor e ela supera o código Java fornecido (não gastei muito tempo ajustando a JVM).
Dito isto, os princípios que o disruptor segue não são específicos do idioma, por exemplo, não espere código C ++ de baixa latência que aloque ou libere do heap.
fonte
Essa pergunta afirma uma premissa incorreta como fato e, em seguida, argumenta sobre essa premissa incorreta.
Vamos nos aprofundar nisso ... "todos os seus pontos de design para minimizar o uso do GC" - simplesmente não é verdade. A inovação no disruptor tem pouco a ver com a GC. O disruptor funciona porque seu design considera inteligentemente como os computadores modernos funcionam - algo muito menos comum do que se poderia esperar. Veja a palestra de Cliff Click http://www.azulsystems.com/events/javaone_2009/session/2009_J1_HardwareCrashCourse.pdf para uma discussão.
É sabido que a LMax é cliente da Azul. Sei em primeira mão que os GCs da Azul são simplesmente uma não emissão - mesmo com montes de 175 GB.
fonte
Acima faz metade da resposta que você está procurando. Você pode encontrar outra metade para concluir o raciocínio não mais do que no blog LMAX :
Conforme admitido pelos desenvolvedores do LMAX, um código como esse pode ser bastante difícil de desenvolver, entender e depurar - mesmo em Java. Ir um nível mais baixo além do que eles estão agora apenas exacerba esse problema, como apontado no artigo da Wikipedia sobre linguagens de programação de baixo nível :
fonte
Se você usar Java como uma linguagem de sintaxe e evitar suas bibliotecas JDK, poderá ser tão rápido quanto uma linguagem não GC compilada. O GC não é adequado para sistemas em tempo real, mas é possível desenvolver sistemas em Java que não deixam lixo para trás. Como resultado, o GC nunca é acionado.
Acreditamos que a linguagem e a plataforma Java têm muitas vantagens sobre o C / C ++ e desenvolvemos e comparamos alguns componentes Java de latência ultra baixa para prová-lo. Falamos sobre as técnicas para fazer isso neste artigo: Desenvolvimento Java sem GC .
fonte
malloc/free
não é adequado para tempo real, já que o tempo de alocação é ilimitado devido à fragmentação.LMAX é uma biblioteca de mensagens entre threads de alto desempenho.
Para ser útil, alguém precisa escrever o código para que cada thread faça um trabalho útil. Dado que o código provavelmente está em Java ou C # e, em seguida, há muito poucas opções de linguagem que se adaptam bem a eles.
Usar C ou C ++ não é uma boa opção, a menos que você queira limitar seus usuários a um único sistema operacional, pois não há um modelo de encadeamento definido neles.
Atualmente, o Java é o padrão para muitos desenvolvimentos de software. Portanto, a menos que você tenha uma boa razão, é a melhor escolha. (Quando em Roma, faça como os romanos…)
A gravação de software de alto desempenho em Java (ou C #) geralmente é feita para provar um ponto…
fonte