Metodo System.gc();

A resposta para realtime é não usar máquina virtual. Deve-se fugir de código intermediário em tempo de execução.
Sobre o gc, seria muito interessante essa opção. Cada situação envolve um tipo de ação diferente, e, infelizmente, o coletor de lixo não consegue prever isso.
Poder ter opção, sempre é bom.

[quote=juliocbq]A resposta para realtime é não usar máquina virtual. Deve-se fugir de código intermediário em tempo de execução.
Sobre o gc, seria muito interessante essa opção. Cada situação envolve um tipo de ação diferente, e, infelizmente, o coletor de lixo não consegue prever isso.
Poder ter opção, sempre é bom.[/quote]

Hoje em dia eu não usaria java para realtime, mas o futuro do realtime é sim dentro de uma vm.
A razão é obvia : o controle de tempo não depende do tipo de aplicação . Se com VM conseguimos ter
aplicações mais rápidas que com codigo estáticamente compilado não seria surpreendente que a VM
possa dar garantia de quanto uma execução demoraria. Fora que a analise dinâmica pode encontrar
padrões que podem ser tratados especialmente . Não é coisa para agora, mas no futuro breve ( mais 5 ou 10 anos).

Eu espero que sim. Mas sobre tempo e performance de aplicações de máquina virtual serem mais rápidas que código nativo, é pura ilusão. A maioria dos benchmarks que afirmam que um bytecode roda mais rápido que código nativo, estão, na maioria(80%) furados.

Fiz uma pesquisa com benchmarks uma vez, e descobri que a velocidade do bytecode sobre o nativo, se deve a otimização que a máquina virtual faz. Então peguei o mesmo software, este em c++, e aumentei a otimização, nos parâmetros do compilador, para nivel 2(nem setei compilação para processador específico), e tive resultados completamente diferentes. Fiz com vários benchmarks que encontrei no google, que diziam que a vm pode rodar mais rápido que código nativo. E todos os testes falaram o contrário.

Além disso, alguns benchmarks tendenciosos comparavam código compilado sem otimização com o Visual Studio 6.0 (compilador bem antiguinho e bem ingênuo, lançado em 1998 ) com o Java 6.0). Se comparar com o mesmo compilador, só que na versão 2008 e código otimizado, o código em C++ costuma ganhar.

Um ponto positivo para o Java é o fato de que a VM e os dados de reflection permitem instrumentação do código não intrusiva e de extrema qualidade. Como a obtida no visual VM, por exemplo.

Conseguimos obter diversas aplicações Java mais rápidas do que as feitas em C++, não pelo fato do Java ser uma linguagem nativamente mais rápida, mas pelo fato de ser facílimo instrumentar, descobrir gargalos, corrigir erros e obter algoritmos mais eficientes.

No C++, dificilmente pode-se fazer instrumentação sem inserir instruções de profiling dentro do código.

[quote=ViniGodoy]Um ponto positivo para o Java é o fato de que a VM e os dados de reflection permitem instrumentação do código não intrusiva e de extrema qualidade. Como a obtida no visual VM, por exemplo.

Conseguimos obter diversas aplicações Java mais rápidas do que as feitas em C++, não pelo fato do Java ser uma linguagem nativamente mais rápida, mas pelo fato de ser facílimo instrumentar, descobrir gargalos, corrigir erros e obter algoritmos mais eficientes.

No C++, dificilmente pode-se fazer instrumentação sem inserir instruções de profiling dentro do código.[/quote]

Sim, é verdade, mas os testes são feitos usando programas simples. Normalmente um laço for sem nada dentro, e outras instruções contando tempo e processando calculos matemáticos.

Esse for vazio é descartado pelo otimizador da jvm, enquanto em um compilador, é necessário setar confugurações. Fazendo isso descobri uma série de Benchs inconsistentes, no google.

Normalmente, o resultado é c++ ser 1 tempo, mais rápido que java. E vendo por esse lado, java é a vm mais rápida delas.

Outra coisa que observamos é o fato do new de delete do Java ser extremamente rápido.

Faça um teste com a criação e destruição de um objeto dentro de um loop. O C++ tem uma implementação bastante inocente: a cada new, reserva-se memória, a cada delete, apaga-se. Isso é feito por solicitações ao SO, extremamente lentas.

No caso do Java, a VM controla os objetos de vida curta. Quando um objeto é deletado, sua memória não é imediatamente desalocada e só ponteiros da VM são atualizados. Ou seja, equivale a uma deleção de custo próximo ao 0. Se um objeto idêntico é requisitado, essa memória é devolvida, quase instantaneamente.

Isso parte de uma observação de que objetos de vida curta estão muito presentes. Segundo os artigos da sun, eles correspondem a mais de 80% dos casos, em média. Tem mais detalhes desse funcionamento aqui: http://www.ibm.com/developerworks/java/library/j-jtp11253/

Para testar, basta fazer algo como:

for (int i = 0; i < 10000000; i++) { Teste t = new Teste(); delete t; }

Tente usar um objeto com vários campos, para o resultado ser mais evidente, e procure zera-los no construtor, como o java e uma aplicação normal fariam.

No C++, é possível fazer otimizações nesse sentido se você sobrecarregar o new e o delete, e fazer você mesmo um memory manager. E, obviamente, essa é uma tarefa extremamente complexa. Claro, no caso do loop acima, seria possível criar t antes do laço e só zerar os valores de t, ao invés de usar new e delete sempre. Mas isso não seria possível caso t fosse um objeto temporário criado numa função, que estivesse sendo chamada por esse laço.

A implementação do Java, entretanto, come mais memória. É o velho trade-off de velocidade versus memória.

[quote=ViniGodoy]Outra coisa que observamos é o fato do new de delete do Java ser extremamente rápido.

Faça um teste com a criação e destruição de um objeto dentro de um loop. O C++ tem uma implementação bastante inocente: a cada new, reserva-se memória, a cada delete, apaga-se. Isso é feito por solicitações ao SO, extremamente lentas.

No caso do Java, a VM controla os objetos de vida curta. Quando um objeto é deletado, sua memória não é imediatamente desalocada e só ponteiros da VM são atualizados. Ou seja, equivale a uma deleção de custo próximo ao 0. Se um objeto idêntico é requisitado, essa memória é devolvida, quase instantaneamente.

Isso parte de uma observação de que objetos de vida curta estão muito presentes. Segundo os artigos da sun, eles correspondem a mais de 80% dos casos, em média. Tem mais detalhes desse funcionamento aqui: http://www.ibm.com/developerworks/java/library/j-jtp11253/

Para testar, basta fazer algo como:

for (int i = 0; i < 10000000; i++) { Teste t = new Teste(); delete t; }

Tente usar um objeto com vários campos, para o resultado ser mais evidente, e procure zera-los no construtor, como o java e uma aplicação normal fariam.

No C++, é possível fazer otimizações nesse sentido se você sobrecarregar o new e o delete, e fazer você mesmo um memory manager. E, obviamente, essa é uma tarefa extremamente complexa. Claro, no caso do loop acima, seria possível criar t antes do laço e só zerar os valores de t, ao invés de usar new e delete sempre. Mas isso não seria possível caso t fosse um objeto temporário criado numa função, que estivesse sendo chamada por esse laço.

A implementação do Java, entretanto, come mais memória. É o velho trade-off de velocidade versus memória.[/quote]

Não seria possível?

for (int i = 0; i < 10000000; i++) {
  Teste t;
  ZeroMemory(&t,sizeof(t));
}

Imagino aqui o tempo ser bem mais curto. Sendo ZeroMemory escrito diretamente em assembly.

Seria, mas considere o caso:

for (int i = 0; i < 10000000; i++) { t.doSomething(); }

E o método doSomething() faz a tal criação e destruição temporárias. No benchmark o problema fica explicito. na vida real, nem sempre.
E considere também que a classe do objeto t não foi implementada por você, mas vem de uma API externa… e aí você já viu o problema.

[quote=ViniGodoy]Seria, mas considere o caso:

for (int i = 0; i < 10000000; i++) { t.doSomething(); }

E o método doSomething() faz a tal criação e destruição temporárias. No benchmark o problema fica explicito. na vida real, nem sempre.
E considere também que a classe do objeto t não foi implementada por você, mas vem de uma API externa… e aí você já viu o problema.[/quote]

Ae sim. Isso é um problema, justamente por eu não ter controle.

Eu adoro quando o desenvolvedor utiliza System.gc() dentro do servidor de aplicação. Principalmente quando coloco no parâmetro de inicialização da JVM: -XX:DisableExplicitGC :twisted:

Isso só vai fazer com que o comando seja desobedecido sempre. Mas não vai gerar nenhum tipo de erro.
Se o desenvolvedor depende vitalmente dessa chamada, está realmente cometendo um erro fatal.

E detalhe, para esse comando ter efeito, você precisa usar o sinal de +, não o de -. É o problema com opções na negativa. Se você usar com -, estará habilitando o explicit gc (como já é padrão), já que estará desligando o “disable”.

[quote=ViniGodoy]Isso só vai fazer com que o comando seja desobedecido sempre. Mas não vai gerar nenhum tipo de erro.
Se o desenvolvedor depende vitalmente dessa chamada, está realmente cometendo um erro fatal.[/quote]

ainda bem que ele não é meu gerente. Se bem que eu nem trabalho com servidores. A maioria dos softwares são simples, e só controlam hardware.

[quote=ViniGodoy]Isso só vai fazer com que o comando seja desobedecido sempre. Mas não vai gerar nenhum tipo de erro.
Se o desenvolvedor depende vitalmente dessa chamada, está realmente cometendo um erro fatal.[/quote]

Essa é a idéia. Conforme apontado aqui neste tópico, através de System.gc() ele sugere que passe o coletor… simplesmente dou uma forcinha para que a sugestão nunca seja aceita. Confio mais na gestão da coleta pela JVM do que pelo desenvolvedor (em ambientes servidor).

Não é bem assim Vini. Na verdade -XX faz parte do prefixo da diretiva, o que esqueci de digitar foi o + antes do DisableExplicitGC:

-XX:+DisableExplicitGC

[quote=Alessandro Lazarotti][quote=ViniGodoy]Isso só vai fazer com que o comando seja desobedecido sempre. Mas não vai gerar nenhum tipo de erro.
Se o desenvolvedor depende vitalmente dessa chamada, está realmente cometendo um erro fatal.[/quote]

Essa é a idéia. Conforme apontado aqui neste tópico, através de System.gc() ele sugere que passe o coletor… simplesmente dou uma forcinha para que a sugestão nunca seja aceita. Confio mais na gestão da coleta pela JVM do que pelo desenvolvedor (em ambientes servidor).

Não é bem assim Vini. Na verdade -XX faz parte do prefixo da diretiva, o que esqueci de digitar foi o + antes do DisableExplicitGC:

-XX:+DisableExplicitGC

existem vantagens e desvantagens.
Como citado, o gc é “burro”. Em muitos casos, você precisa ajustar para sua situação.


http://www.oracle.com/technology/global/lad-pt/pub/articles/brahms-tuning.html