System.gc()

Ja vi muita gente criticar o uso do tal System.gc, mas a minha pergunta é, o GC do java realmente eh eficaz? Vim da programação em C++ onde se tinha a prática de criar um objeto e ja criar o método de destruição do mesmo, e em java tenho medo, ja que algumas vezes chego a criar 20 objetos de uma vez só e até agora não me preocupei com performance ja que estou trabalhando com uma massa de dados pequena.
Quando eu implementar meu sistema, que tera um tráfego de dados em memória muito grande, vou sentir a diferença ?? Ou realmente o GC cumpre o que promete ??

Afinal de contas se o comando system.gc existe é pra ser usado, ou não ??¿¿
Valew galera.

Boa Tarde…

( não sou grande conhecedor porém tive de usar o System.gc recentemente para “limpar” um pouco da “carga” de minha aplicação e posso lhe dizer que funcionou perfeitamente… )

Apesar da chamada explicita ao System.gc não faz com que o mesmo seja executado imediatamente, ele poderá ou não ser executado pela JVM até onde eu sei, digamos assim, ele é apenas um “aviso” que o coletor de lixo precisa ser chamado,

mas concordo com você, se existe, é porque pode ou deve ser chamado,
porém, quem sabe, algum GURU do fórum possa lhe dar uma idéia melhor…

A Coleta de lixo é responsabilidade da maquina virtual java.

Assim, a confiabilidade dela depende do vendor, afinal eu posso usar a maquina da Sun, da HP, etc.

Perceba que o javadoc desse método fala em:

Sim. O garbage collector é muito, muito, muito eficiente.
Mais do que o new e delete do C++, quando o assunto são as aplicações do dia-a-dia.

Por várias razões:
O principal delas: Ele é capaz de identificar gerações de objetos. Objetos muito novos, recém criados, são destruídos do programa, mas sua memória não é desalocada do heap. Assim, sua desalocação tem custo 0 (já que efetivamente não ocorreu). A vantagem disso é que normalmente objetos desse tipo logo são recriados, e o Java poupa outra alocação do heap, e novamente, quando realocados novamente é provavel que o new vá ter um custo próximo ao zero (incluindo apenas o custo de limpeza do espaço de memória).

Apenas objetos de “gerações mais velhas” são realmente desalocados. A gerência de memória da VM também permite a identificação de áreas contínuas de memória, onde a desalocação pode ocorrer em uma única operação de free (ou delete, no caso do C++), otimizando assim requisições para o sistema operacional.

É claro que essa política toda consome mais memória.

Dá uma lida nesses artigos, que explicam o funcionamento do garbage collector e mostra maneiras de ajusta-lo:



http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html

E, geralmente, não é nem sequer necessário chamar o System.gc()! :slight_smile:

O GC é ótimo, mas não é determinístico, por isso Java não “serve” para Sistemas Real-time… Mas se seu sistema não precisa ser RT, não esquenta!

http://www.onjava.com/pub/a/onjava/2006/05/10/real-time-java-introduction.html

Se o problema é o “gc” não seria o caso de utilizar uma VM específica para sistemas real-time (ou construir um, na falta de)?

Existem implementações, só que pagas…

http://java.sun.com/javase/technologies/realtime/

http://www-306.ibm.com/software/webservers/realtime/

Eu considero uma falha, me corrijam se eu estiver errado. Disponibilizar um comando para chamar o GC sendo que ele não é executado quando chamado, ele apenas sugere a maquina virtual como diz o artigo, mas enfim.

Então realmente não preciso chamar o dito cujo…

[quote=Guitar_Men]Eu considero uma falha, me corrijam se eu estiver errado. Disponibilizar um comando para chamar o GC sendo que ele não é executado quando chamado, ele apenas sugere a maquina virtual como diz o artigo, mas enfim.

Então realmente não preciso chamar o dito cujo… [/quote]

Não precisa.

Falha pq? Não é uma boa dar a sugestão?
Está completamente documentado (no javadoc do comando inclusive) que não é uma obrigação a JVM cumprir.

Mas para ser bem sincero, a JVM da Sun normalmente atende ao comando, exceto nas situações onde ele é chamado por várias vezes sucessivas, como dentro de um loop.

Não.
O que é para ser usado é boa orientação a objetos. Saber usar os objetos certos (especialmente collections)
e saber quando poderá haver objetos perdidos na memoria. O cg não faz milagres. Ele não desaloca objetos com referencias. Então se vc tiver uma lista que guarda num atributo estático e enche a lista com trilhões de objetos vc está pendido por um OutOfMemoryException.
Esqueça o gc e concentre-se em OO e em saber o que está a fazer e que implicações isso tem.

Mas ai que esta caro sergio, a própria OO se confunde, como eu disse em C++ a OO diz para ao criarmos um objetos implementarmos a sua destruição logo em seguida, agora no Java, como quem controla a memória eh a VM fica meio distorcido entende ??

Bem pelo contrário.

No C++, você pode deletar um objeto que está sendo usado por outro objeto. Isso é uma coisa distorcida, já que o outra objeto fica com uma coisa na mão que parece o objeto, mas não é. É inváldo, dangling pointer, e um pau certo em runtime.

Em segundo lugar. Você pode criar um objeto, retirar todas as referências dele e ter um “objeto perdido”, ou o tradicional unrecoverable memory leak. Isso acontece tipicamente se você deu um new e seu código lançou uma exceção.

No Java, a destruição ocorre “logo” que vc desreferencia o objeto. Não há memory leaks irrecuperáveis e nem dangling pointers. Você pode lançar exceções sem preocupação. Se o objeto é necessário, ele existe, sem confusão. Se ele não é necessário, ele deixa de existir.

Não existem preocupações com gerência de heap e stack, já que tudo, a principio, funciona da mesma forma.

Como eu falei, o garbage collector é eficiente o suficiente para ele deixar de ser uma preocupação.
Os códigos modernos em C++ também estão tentando se livrar da preocupação de deletar objetos através de smart pointers (como aqueles presentes na Boost e na TR1), que implementam o conceito de RAII (Resource Aquisition is Initialization). O conceito é muito bom, evita dores de cabeça, e é mais natural depois que você percebe que realmente funciona.

eita, quanto mais eu leio, mais duvidas eu tenho !

Acho q vou voltar a ser “montador de micro”

Errado. Não é a OO que diz isso. é o C++
Em java a destruilção já existe: é inerente. Existe até um método finalize() em todos os objetos que é executando antes da destruição.
O que eu quize dizer foi: pense nos objetos e nas relações entre eles e esqueça os bitse bytes.
(pelo menos até estar mais familiarizado com o java).

O controle de objetos é responsabilidade da JVM, não sua. Não precisa se preocupar com isso.

Pois é, mas me da medo não controlar os MEUS objetos não acha ?? hahahaha zuera, mas leva tempo pra se acostumar

Ouvi falar que o método finalize() nem sempre é chamado, isso procede?

Nunca ouvi isso. Porque não haveria de ser chamado ?
O que pode acontecer é que o codigo do metodo finalize pode colocar o objeto de volta como um objeto não eligivel para recolha e isso estraga o gc.

Ah então é isso :slight_smile:

Quando a máquina virtual “termina” os métodos finalize() não são invocados à menos que você defina o contrário com runFinalizersOnExit, porém a utilização deste pode causar problemas de deadlock ou a finalização de objetos que não deveriam ser finalizados.

bem, achei muito interessante esse topico ja que estou com problemas desse tipo. tenho um soft totalmente funcional so esta com um grande problema de memory leaks e estou tentando resolver. e acontece q nao estou encontrando onde esta esses vazamentos de memorias. uso hibernate e ele me retorna um list nao referenciado no qual utilizo o metodo iterator e vou lendo um por um e depois finalzo o iterator. acontece q consultas sucessivas ao banco deixa o programa extremamente lento pois comeca a fazer swap

alguma sugestao?