Ligação entre o Garbage Collector e Minimização de uma janela

Boa noite!

Eu pesquisei na Internet e não achei nada relacionado.
Achei várias coisas sobre GC, mas nada relacionado a minha dúvida.

A questão é a seguinte:

  1. Tenho uma aplicação que importa arquivo de aproximadamente 50 MB para o banco de dados;
  2. Podem ser importados vários arquivos ao mesmo tempo, cada um com sua thread;
  3. Cada thread ocupa uma média de 5 MB para importação do arquivo;

Ou seja, se eu importar 5 arquivos, o aplicativo vai ocupar 50 MB em memória.
Fazendo alguns testes eu percebi que:

  1. Deixei o aplicativo por mais de 1 hora aberto com um Timer chamando o System.gc() ou Runtime.getRuntime().gc() de 1 em 1 minuto. Aparentemente não liberou nada, na realidade não sei se agendou uma chamado ao GC, não sei se chamou.
  2. Quando eu minimizo a janela, a memória ocupada cai drasticamente para algo em torno de 15 MB.

A pergunta é:

Qual a relação de minimizar uma janela com o GC?
Quando o Windows minimiza uma janela o GC faz o serviço dele?

Não entendi isso, e também não quero dar a “dica” pro usuário que se o software estiver ocupando muita memória depois de importar 50 arquivos, ele pode minimizar a janela que melhora.

É isso ae.

Valeu.

Eu acho que não há ligação, até pq não há nenhuma garantia que o gc vai rodar.
O que pode está ocorrendo é o seguinte toda vez que minimiza sua janela o
sistema operacional joga sua aplicação na memória virtual, assim liberando memoria
fisica.

Quando você minimiza a janela, o Java “em si” não toma nenhuma providência para reduzir a memória ocupada, tanto que a quantidade de memória virtual (RAM + Swap) não muda um dígito sequer, assim como a “private memory” (memória exclusiva desse processo, que não é compartilhada com outras aplicações).

É o Windows que percebe que a aplicação não está sendo usada (porque todas as janelas estão minimizadas, o que o faz entender que essa aplicação foi para “background” e deve receber o tratamento de uma aplicação “background”), e reduz agressivamente uma coisa chamada “working set”, que é a quantidade de memória RAM que está sendo efetivamente ocupada naquele presente momento. Algumas aplicações (como o MS Office) foram designadas pela Microsoft para que seu “working set” caia para quase zero se elas não estiverem em uso; mas o Java não se beneficia tanto dessa otimização do Windows, já que ele deixa muitas coisas ativas (como a thread de “garbage collection” e a thread do “finalizer”).

Quando você “desminimizar” a janela, o Windows vai tentar restaurar o “working set” dessa aplicação, e irá fazê-la consumir a memória física que estava consumindo antes, à medida que ela for sendo acessada.

Acontece exatamente o que o Daniel falou.

A memória virtual não muda, só a física mesmo.
Windows manda pra swap e só volta pra física de acordo com a necessidade mesmo.

Depois que a thread de importação termina, a memória deveria ser liberada, correto?!

De qualquer forma, valeu!
Respondeu a minha dúvida.

Boa pergunta - dependendo do que foi feito nessa thread, a memória não será liberada assim sem mais nem menos. Você precisaria de um profiler de memória para ver se isso ocorre ou não.

Um objeto só é recolhido pelo GC quando não há mais referências para ele, se você mantiver referências para o Objeto Thread, logo ele não será recolhido pelo GC, observe que o fato da thread terminar não quer dizer que ela será recolhida pelo GC.

Uma boa prática é setar para null os objetos que não estçao mais sendo usados.