Metodo System.gc();

Estranhíssimo. Mas a sun nunca abriu mão do direito único e exclusivo que a VM tem de controlar o gc.
Já foram feitos pedidos para criar comandos que suspendam o gc, ou que forcem sua execução, mas implementações disso sempre foram negadas.
[/quote]

Não é estranho, aliás é de esperar e totalmente óbvio se você pensar na razão de ter um CG para começo de conversa: ambiente gerenciado.

Ora se o ambiente é gerenciado, em particular a memória, deixar que o programador interfira com isso é totalmente contra o objetivo pois tornaria a VM um ambiente não-gerenciado. O fato de poder sugerir já é muito bom, embora se vc esquecer que isso existe nunca terá problemas.

Se tiver problemas de memoria com java o problema está na sua aplicação , nas API que usa ou na pouca memoria ram disponivel.
mandar o GC correr, não vai alterar a qualidade destas 3 coisas…

O que é estranho é o método gc existir, e não que a sua implementação seja opcional (lembrar que o java é uma especificação).

Em teoria, num ambiente gerenciado perfeito, o GC coletaria o lixo na hora certa, usando tempo de processamento mínimo, mantendo a aplicação sempre eficiente. Bem, não vivemos em sonhos.

System.gc() existe por pragmatismo.

o grande problema é que o gc não é inteligente, como postado no link anteriormente. http://developers.sun.com/learning/javaoneonline/j...n=TS-5419&yr=2008&track=javase

Se a sun permitisse o controle dele, pelo desenvolvedor, estaria aumentando o poder do java.

[quote=sergiotaborda]Se tiver problemas de memoria com java o problema está na sua aplicação , nas API que usa ou na pouca memoria ram disponivel.
mandar o GC correr, não vai alterar a qualidade destas 3 coisas…[/quote]

Ninguém falou em rodar o gc por problemas de falta de memória. O problema é o gc rodar em horas impróprias, como os casos que citamos acima.

Não acho estranho que esse método exista. Aliás, também acho que deveria ser obrigatória a execução do gc(). Isso não torna o ambiente não gerenciado, de forma alguma. Ninguém está falando aqui em não ter um garbage collector, ou deletar objetos diretamente.

[quote=juliocbq]o grande problema é que o gc não é inteligente, como postado no link anteriormente. http://developers.sun.com/learning/javaoneonline/j...n=TS-5419&yr=2008&track=javase

Se a sun permitisse o controle dele, pelo desenvolvedor, estaria aumentando o poder do java.[/quote]

Vc está assumindo que 1 desenvolvedor é mais oportuno que um algoritmo desenvolvido e comprovando por
dezenas (senão centenas, quiça milhares ) de desenvolvedores. Isso simplesmente não é verdade.

O poder do CG , como do hotspot, está em exactamente ninguem poder por a mão.
Veja, se existisse uma api de controle do CG ninguem poderia lançar um CG que não fosse compativel com ela.
se ela desse muito poder ao programador, nunca teriamos um CG apto para realtime.

A Sun, nem o JCP devem primitir este tipo de promiscuidade. Nunca!

[quote=ViniGodoy]
Não acho estranho que esse método exista. Aliás, também acho que deveria ser obrigatória a execução do gc(). Isso não torna o ambiente não gerenciado, de forma alguma. Ninguém está falando aqui em não ter um garbage collector, ou deletar objetos diretamente. [/quote]

Mas indirectamente estão dizendo que querem controlar quando ( e possivelmente como) o CG roda. Isso é mesmo que o CG
não ser mais independente da aplicação.

Veja,Iterator.remove tem implementação opcional. Isto significa que vc pode mandar deletar e não vai acontecer. Inesperado talvez
mas a especificação tem que ser assim para dar conta de Arrays.asList().iterator().remove() que não pode remover os itens já que o proxy é imutável. O mesmo acontece com o CG. Porque ele é isolado e vc não o pode comandar (pode sugerir, não comandar) ele tem muita mais flexibilidade. É quase que o principio de hollywood (“don’t call us, we will call you”) so que “don’t call us, we know what to do better than you”. O CG precisa ser isolado (ou seja, náo pode existir forma de o comandar)

Desculpem interromper a discussão*, mas esse link tá quebrado… alguém sabe se tem um outro que funcione?

  • Muito interessante por sinal.

Desculpem interromper a discussão*, mas esse link tá quebrado… alguém sabe se tem um outro que funcione?

  • Muito interessante por sinal.[/quote]

Peguei o link errado. Esse aqui.

http://research.sun.com/jtech/pubs/04-g1-paper-ismm.pdf

[quote=sergiotaborda][quote=ViniGodoy]
Não acho estranho que esse método exista. Aliás, também acho que deveria ser obrigatória a execução do gc(). Isso não torna o ambiente não gerenciado, de forma alguma. Ninguém está falando aqui em não ter um garbage collector, ou deletar objetos diretamente. [/quote]

Mas indirectamente estão dizendo que querem controlar quando ( e possivelmente como) o CG roda. Isso é mesmo que o CG
não ser mais independente da aplicação.

Veja,Iterator.remove tem implementação opcional. Isto significa que vc pode mandar deletar e não vai acontecer. Inesperado talvez
mas a especificação tem que ser assim para dar conta de Arrays.asList().iterator().remove() que não pode remover os itens já que o proxy é imutável. O mesmo acontece com o CG. Porque ele é isolado e vc não o pode comandar (pode sugerir, não comandar) ele tem muita mais flexibilidade. É quase que o principio de hollywood (“don’t call us, we will call you”) so que “don’t call us, we know what to do better than you”. O CG precisa ser isolado (ou seja, náo pode existir forma de o comandar)[/quote]

A opção de escolher quando o gc vai rodar já existe com esse método System.GC(). Ele resolveu um problema sério de performance que eu tinha num soft aqui. Só estamos comentando sobre a praticidade de ter controle maior sobre o coletor. Por exemplo, de poder escolher como limpar a ram.

http://research.sun.com/jtech/pubs/04-g1-paper-ismm.pdf

O link acima fala das falhas do coletor de lixo, as novas funcionalidades que serão implementadas no próximo.

Para entender um pouco mais o CMS(Concurrent Mark-Sweep GC): http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html

Até!

Não, não existe. System.gc() dá-lhe a opção de sugerir que o GC rode, não lhe dá a opção de escolher quando roda.
A decisão ainda é do CG e se ele quiser pode simplesmente ignorar a sua sugestão.

Se vc resolveu um problema de performance usando GC o seu sistema não rodará fora da jvm onde o está usando, e portanto não mais será portável. É porque um software java tem que ser portável que ele não pode depender do GC.

Lembra-se da Inversão de Controle ? Aqui é um lugar onde ela já está feita. O que vcs sugerem é totalmente contra o conceito de ter um GC.

O GC não é uma api bacana de gerenciamento de memoria que vc usa nos seu programas C que vc precisa ficar tunando.
O GC é algo à parte. Tão isolado quanto o compilador JIT. Tentar comandar estas coisas em java é como , em C, tentar comandar o que o processador irá fazer a seguir.

A seguir vc vão querer ter controle determinista sobre threads…
Não ha porquê e a sun/jsp faz muito bem em desacoplar as coisas.

[quote=sergiotaborda][quote=juliocbq]
A opção de escolher quando o gc vai rodar já existe com esse método System.GC().
[/quote]

Não, não existe. System.gc() dá-lhe a opção de sugerir que o GC rode, não lhe dá a opção de escolher quando roda.
A decisão ainda é do CG e se ele quiser pode simplesmente ignorar a sua sugestão.

Se vc resolveu um problema de performance usando GC o seu sistema não rodará fora da jvm onde o está usando, e portanto não mais será portável. É porque um software java tem que ser portável que ele não pode depender do GC.

Lembra-se da Inversão de Controle ? Aqui é um lugar onde ela já está feita. O que vcs sugerem é totalmente contra o conceito de ter um GC.

O GC não é uma api bacana de gerenciamento de memoria que vc usa nos seu programas C que vc precisa ficar tunando.
O GC é algo à parte. Tão isolado quanto o compilador JIT. Tentar comandar estas coisas em java é como , em C, tentar comandar o que o processador irá fazer a seguir.

A seguir vc vão querer ter controle determinista sobre threads…
Não ha porquê e a sun/jsp faz muito bem em desacoplar as coisas.

[/quote]

Meu soft roda em qualquer so. Não usei nenhum recurso nativo de sistema, então ele é totalmente portável. Só sugeri para que ele ( o GC), limpasse a ram antes de acumular objetos. E resolveu meu problema, e o do vini, no jogo dele.

Pois não seria ótimo? :smiley:

Alguém tá programando na plataforma errada :lol:

Ele roda em qualquer SO, desde que a JVM seja a da Sun, fora dela nada é garantido! Veja bem, não estou discordando da utilidade do System.gc(), mas sim do fato de sua implementação ser opcional. Continue lendo…

[quote=sergiotaborda]Vc está assumindo que 1 desenvolvedor é mais oportuno que um algoritmo desenvolvido e comprovando por
dezenas (senão centenas, quiça milhares ) de desenvolvedores. Isso simplesmente não é verdade.[/quote]
Olá Sérgio,
Eu sempre pensei dessa forma, achava que chamar o System.gc() era coisa apenas de POGramador que não toma cuidado com performance e usa “força bruta” para tentar liberar um pouquinho de memória.
Mas com os exemplos reais do Vini e do Julio vi que esse comando tem o seu papel quando usado na situação certa, e vou dizer o que penso disso através de uma parábola :slight_smile:

Sabe o que tenho notado?

Eu e o julio sempre entramos em debates aqui porque temos vivência em sistemas de tempo real. Mesmo que seja apenas soft real time.

A maioria aqui projeta sistemas comerciais, onde uma espera na casa de segundos é tolerável. Agora, mudem para algo relacionado a vídeo, áudio ou sinalização para hardware, que vão ver que as coisas mudam um pouco de figura.

Mesmo o ser humano é muito mais sensível quando o assunto é aquela “congelada” no meio de um filme ou jogo. Ela pode durar 1/10 de segundo, e você já terá um usuário insatisfeito. Um hardware, então, nem se fala. Alguns milisegundos a mais podem representar uma conexão perdida ou uma negação de serviço. Garanto a vocês que lidamos com software muito otimizado. Para se ter uma idéia, algumas versões dos softwares que eu desenvolvia envolviam horas dedicadas a otimização e profiling.

A analogia com o xixi foi boa. Aliás, bastante perfeita com o problema do gc.

Quanto ao problema das threads: o java nunca prometeu gerenciar threads. Aliás, é uma tarefa que a VM delega ao SO, portanto, nem sequer dá qualquer garantias de que threads sequer existirão.

É possível obter controle determinista sobre threads usando filas e sincronização, embora isso seja uma incrível burrice. Outra opção mais determinista seria reduzir o número de threads ao de processadores, e fazer você mesmo o escalonamento das tarefas no sistema. E essa é uma opção bastante comum em jogos.

Vai me desculpar, mas não existe qualquer lógica em seus argumentos. Não há qualquer analogia entre portabilidade e a chamada ao gc. Não estavamos falando em gerenciar o gc na mão, mas em informa-lo que uma sessão crítica do nosso software vai começar e que, no passado, pode haver muita coisa criada e que pode ser coletada. Trata de dizer ao gc que se ele puder limpar agora para não limpar depois, melhor.

E qual é o conceito de se ter um gc?

[quote=sergiotaborda]O GC não é uma api bacana de gerenciamento de memoria que vc usa nos seu programas C que vc precisa ficar tunando.
O GC é algo à parte. Tão isolado quanto o compilador JIT. Tentar comandar estas coisas em java é como , em C, tentar comandar o que o processador irá fazer a seguir.

A seguir vc vão querer ter controle determinista sobre threads…
Não ha porquê e a sun/jsp faz muito bem em desacoplar as coisas.[/quote]

Engraçado, o próprio gc da sun tem diversas opções de tuning, inclusive com documentação sobre como fazer isso. E o método System.gc() existe. A próxima versão de gc poderá até ter metas de desempenho, fornecidas pelo programador. A argumentação da Sun contra o gc nunca envolveu “o conceito de gc” e sim, dificuldades técnicas de implementação ou liberdade de implementação futura.

Vamos lá a ver uma coisa, devo tar falando spranglish…

incovar System.gc() não dá garantia de chamada do CG. Pensemos que temos duas implementações de GC , A e B.
A acata a chamada a gc () como a da sun. B, não. simplesmente ignora.

Agora vc desenvolve um sistema usando a jvm com o cg A. Vc descobre que tem problemas de memoria /performance. Vc então decide chamar system.gc() e descobre que isso resolve o seu problema. Pronto, a sua aplicação está pronta.

Vc manda a aplicação para o cliente que usa uma jvm que corre um cg do tipo B. A sua aplicação continua apresentando o mesmo problema de performance que antes pois a chamada a .gc() não faz nada. A portabilidade da sua aplicação foi pró espaço.
Das duas uma : ou vc estabelece “esta aplicação só funciona na jvm com cg do tipo A” e deixa o cliente se virar para arranjar uma, ou
vc altera a sua aplicação para não precisar invocar o .gc().

É óbvio que .gc() estabelece uma dependencia da JVM. E , como se lembrarão, a jvm da sun não é a única do mundo.

Este cenário é ainda pior em ambiente embarcado. Aqui a chance de usar uma jvm sun é pequena e a chance de estar usando uma jvm tipo B é grande. No cenário embarcado é ainda mais importante a portabilidade e amarrar a performace ao tipo de GC usado por baixo dos panos não é bom. Claro que aqui tb vale a opção “aplicação homologada para o aparelho,X,Y,Z,…”

Existe um outro mundo, e tlv seja esse em que o vini e o julio vivem, em que uma aplicação é feita e otimizada para um certo ambiente. Isso é real e funciona. Até que o ambiente muda e começa tudo de novo. Isso não é mais profiling da aplicação, mas sim do stack inteiro. Isso é tudo muito bom, mas não é o espirito de uma app java. Se vc vive nesse mundo tlv outras plataformas sejam melhores. Java ainda não é para coisa realtime.

O ponto é o seguinte : vc pode informar o gc que agora seria uma boa hora para corre-lo ? sim. isso se chama educação.
A performance da sua aplicação pode depender de chamar ou não o gc ? Não. Isso é uma amarração perigosa. É como usar uma API que só funciona no windows. Deve ser feito ? Não. Pode ser feito ? Pode, mas a custo da aplicação não ser mais portável.
Se a aplicação não é mais portável não ha porque fazê-la em java. Use alguma plataforma nativa ao OS (.NET no windows, C++ no linux , Objetive-C no mac, etc…)

Ok, mesmo sabendo isso ainda prefere java devido a outras facilidades ? Ok. Mas não espere que a especificação da JVM mude para acomodar esse tipo de aplicação que vai contra o costume e os bons princípios da plataforma.

[size=9]
E só um adendo, não de pode dizer que a JVM delega o tratamento de threads para o OS. Não está especificado o que ela faz em relação a isso.
No windows e no linux e na jvm da sun até pode ser que seja assim, mas não podemos partir disse principio ( o que aliás não adiantaria de nada).
Em alguns OS (como no Palm) onde não ha thredas nativas nem processos, a jvm tem que usar green threads. A área de threads é uma das que menos garantias tem. Básicamente vc sabe que run() será chamado. Não sabe como,quando nem por quem.[/size]

Ok, sob esse ponto, você está certo. Ele fica vinculado a uma única VM. A sorte é que se vincular a VM da Sun, vc estará se vinculando a aproximadamente 90% das VMs do mecado, pelo menos no caso das aplicações web e desktop. Outros ambientes já não são muito multiplataforma mesmo, e sua aplicação acabará um tanto específica.

Agora, note que hoje o comando só fere uma boa prática de programação justamente pelo seu caráter opcional, que é exatamente o que estamos argumentando contra. Tanto eu quanto o julio sabíamos que esse comando não seria uma panacéia. É na verdade um placebo. Veja que, mesmo que ele seja obrigatório, uma fase de um jogo longa, ou um vídeo longo ainda poderão gerar coletas de lixo… E, realmente, é uma coisa que teremos que tolerar.

Por isso outros defensores de mais controle no gc() sugerem uma forma de paralizar o gc completamente e reativa-lo mais tarde. Essa seria a única forma de garantir algum comportamento de tempo real por algum tempo. Seria isso ir contra o princípio da coleta de lixo, ou do Java? Há muita gente que acha que não e eu me encontro entre elas.

Por outro lado, o java permaneceria inadequado para aplicações de tempo real, pois não é possível manter o coletor de lixo desligado para sempre. Por isso, embora eu ache que esse conceito não seja “filosoficamente antagônico”, não vejo a introdução de um comando desses como algo tão útil assim.

A solução encontrada pela sun foi intermediária e, para o caso do Java, eu considero adequada. Ela vai permitir que o gc assuma compromissos de tempo, dentro da capacidade do hardware e das configurações que estiver rodando. Ele fará isso coletando menos lixo, ajustando melhor o momento das coletas longas, entre outras coisas. Por mim, isso já é mais do que suficiente, e uma solução muito mais elegante do que fazer o programador controlar diretamente o gc. Nada mais é do que melhorar os parâmetros de tuning.

[quote=ViniGodoy]
Por isso outros defensores de mais controle no gc() sugerem uma forma de paralizar o gc completamente e reativa-lo mais tarde. Essa seria a única forma de garantir algum comportamento de tempo real por algum tempo. Seria isso ir contra o princípio da coleta de lixo, ou do Java? Há muita gente que acha que não e eu me encontro entre elas.

Por outro lado, o java permaneceria inadequado para aplicações de tempo real, pois não é possível manter o coletor de lixo desligado para sempre. Por isso, embora eu ache que esse conceito não seja “filosoficamente antagônico”, não vejo a introdução de um comando desses como algo tão útil assim.

A solução encontrada pela sun foi intermediária e, para o caso do Java, eu considero adequada. Ela vai permitir que o gc assuma compromissos de tempo, dentro da capacidade do hardware e das configurações que estiver rodando. Ele fará isso coletando menos lixo, ajustando melhor o momento das coletas longas, entre outras coisas. Por mim, isso já é mais do que suficiente, e uma solução muito mais elegante do que fazer o programador controlar diretamente o gc. Nada mais é do que melhorar os parâmetros de tuning. [/quote]

Mas o que importa dessa hsitoria é que isso foi possivel porque é possivel modificar o CG sem ter que modificar as aplicações.

O meu ponto é que o CG é um componente automático, no sentido de “não põe aqui a mão , mané!” (hands-off)
Se for colocada algum método que permite controlar o que o CG faz ou como ou quando faz, ele deixa de ser automático.
Coisas informativas (hints) tudo bem, porque em ultimo caso sempre será o CG a decidir. Isto seria um tuning, mas um tuning não dependente. Neste tipo de API não vejo nenhum mal tecnico. O problema é conceptual como no caso de threads.

A JVM da Sun acata o .gc() se vc chamar com parcimónia, mas será que acata se chamar a cada método ? Convenhamos que se sim, essa não é uma boa implementação do GC. Este tipo de recurso tem que ser protegido do abuso do programador.

O “vedadeiro” real time não se faz com um GC melhor, se faz com uma JVM diferente. A melhor forma de garantir que o GC não afetará o tempo da aplicação é não ter nenhum lixo para coletar. Ora isso só é possivel se não houver nenhum objeto “morto” no heap, e isso só é possivel se o objeto estiver no stack…pois, só que objetos não ficam no stack…ficam ?
Na real time JVM ficam. Nem todos os objetos são aptos a ficam no stack, mas a JVM faz um exercicio interessante ao não popular o heap indescriminadamente. Esta lógica é critica em real time verdadeiro (do qual vidas dependem) mas com o tempo poderá ser o padrão da jvm em que heap e stack passará a ser uma diferenciação semântica. Tudo isto só para dizer que a resposta java para o real time não é (apenas) mudar o GC.