Duvida sobre Objetos, JFrame e componentes visuais

Bem pessoal, estou com uma duvida referentes a objetos criado por componentes visuais.

Vamos dizer que eu tenho Menu e ao ser clicado, abre-se um JInternalFrame. Dentro desse, existe varios componentes como JTextField e Button. Na hora que é criado o objeto desse JInternalFrame, é criado tambem o objeto dos componentes ou nao funciona bem assim?

Se a resposta for sim a esta pergunta, quer dizer que se eu fechar o JInternalFrame, os objetos dele tambem serao excluidos da memoria?

Quanto tempo o GC demora para limpar esses dados da memoria?

Abraços

Sim, funciona assim.

Se o JInternalFrame for a única ligação de todos esses objetos com o resto do mundo, todos eles serão excluídos assim que o JInternalFrame for definido para null. O garbage collector é capaz de identificar “ilhas” de objetos não acessíveis, mesmo que eles se referenciem entre si.

É impossível prever. Mas é garantido que ele fará uma pelo menos uma execução antes de um OutOfMemoryError.

Bem, eu estou criando o projeto pelo NetBeans mesmo, entao, acredito que os componentes estao sendo referenciandos apenas no JInternalFrame mesmo.

Sobre esse OutOfMemoryError, o que seria isso?

Eu fiz um teste aqui, executei um programa em Java e depois abri o gerenciador de tarefas do windows. Na hora que eu abri o JInternalFrame, realmente, o uso de memoria aumentou. Depois, fechei o JInternalFrame e esperei um tempo para ver se diminuia. Nao aconteceu isso. É por causa desse OutOfMemoryError?

Abraços

O OutOfMemoryError é o erro da VM dizendo que faltou memória. A virtual machine garante para você que antes de disparar um erro desses, ela terá rodado o garbage collector para fazer uma coleta de lixo completa. E, só se essa coleta de lixo não liberar a memória necessária para o que você quer, ela irá disparar o tal erro.

Assim, pouco importa para quem programa o momento exato que o gc vai rodar, o que importa mesmo, é a certeza de que, se houver algum lixo no gc, ele será coletado ANTES de faltar memória.

Agora, quanto à sua observação, existem duas coisas diferentes:

a) A memória que a sua VM controla (heap space);
b) A memória que sua aplicação conhece.

Entenda que alocar e desalocar memória no SO é um processo caro. Muito caro. E que quanto mais contínua for a memória alocada, melhor. Os projetistas da Sun perceberam que alocar e desalocar memória para objetos era um processo extremamente comum, e que uma das grandes formas de otimizar a velocidade de execução do Java seria evitar essa alocação.

O que fizeram então. Assim que sua VM sobe, ela aloca uma grande quantidade de memória, por exemplo, 64k. Esse é o heap.
Mesmo que seu programa aloque apenas 1 único int (32 bytes). A medida que sua aplicação necessita de mais memória, esse heap vai aumentando em 50% seu tamanho. Então, ao locar 64.001 bytes, o heap subiria de 64k para 64+32=96k. E assim sucessivamente. O java controla então, dentro desse heap o que é memória livre e o que é realmente usado para sua aplicação. Esse heap tem um tamanho máximo, que por padrão é de 64MB (ou seja, mesmo que vc tenha 3GB de memória livre, a VM dará OutOfMemoryError se sua aplicação ultrapassar os 64, a menos que uma diretiva como -XMX aumentando o heap seja dada para a JVM).

O que acontece então, é que a medida que você desaloca memória, o Java não irá devolve-la imediatamente para o SO. O que ele faz, é apenas marcar essa memória como livre no heap. Assim, se você precisar de memória novamente logo em seguida, a VM não precisará pedir para o SO (processo lento).

É isso que ocorre com o seu JInternalFrame. Você libera ele da memória, e ele é devolvido para o heap da VM, que tem o tamanho que você observa no seu gerenciador de tarefas. Para a aplicação, aquela memória foi liberada já que, se for necessária, o java reutilizará aquele espaço. Mas para o SO, não. Quando essa memória será liberada de verdade? Quando a VM detectar que aquela memória ficou sobrando por muito tempo, e não temos um controle exato do que a VM define como “muito tempo”. O fato é que quando a memória for desalocada, a VM fará primeiro uma compactação do heap e então irá liberar um único bloco de memória, bastante grande, referente a todo espaço não utilizado. E isso otimiza muito o processo de liberação junto ao SO, que é lento.

Para mais informações: