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:
Tenho uma aplicação que importa arquivo de aproximadamente 50 MB para o banco de dados;
Podem ser importados vários arquivos ao mesmo tempo, cada um com sua thread;
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:
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.
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.
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.
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.