Lixo

Garbage Collector (GC)

Java é considerada uma managed languaged e, portanto, os objetos que são criados e armazenados no Heap são automaticamente liberados da memória quando um processo especial os elege para tal.

Esse processo é conhecido como Garbage Collector (coletor de lixo) e

…foi inventado por John McCarthy por volta de 1959 para resolver problemas de gerenciamento manual de memória em Lisp.

Linguagens como C e C++ não possuem este mecanismo e a responsabilidade pela liberação de memória fica com o programador, que deve invocar o método free para os objetos que não serão mais utilizados. Algo parecido ocorre em Visual Basic, mas nela o programador deve apontar o objeto para null.

O mecanismo do GC em Java é simples: se um objeto não puder ser alcançado por uma referência a ele na Stack, então ele será marcado como elegível para coleta. Objetos estáticos, cujas referências ficam no Metaspace, nunca serão eleitos pois nunca perdem a referência.

Embora seja automático e executado em uma Thread independente, é possível invocar o processo por meio do método System.gc(). Entretanto essa chamada apenas sugere que o GC seja executado. Sua execução fica a cargo da JVM, que decidi fazê-lo ou esperar por outro momento mais oportuno.

Na versão 1.8 e anteriores, a JVM alocava a quantidade de memória definida na variável -Xms e mesmo após a execução o GC essa memória permanecia alocada. A partir do Java 11, é possível que a memória seja liberada e devolvida ao sistema operacional. Por questões de performance pode ser que isso não ocorra.

Essa diferença de comportamento nas versões é interessantíssima. Abaixo segue um gráfico mensal de uso de memória de uma aplicação Web na versão 1.8 do Java.

Gráfico de uso de memória

Como pode-se observar, a quantidade de memória apenas diminui para o patamar inicial em momentos de reinício do servidor, ocorrido entre 01/12 e 03/12. Quem não conhece o mecanismo, pode achar que ele não está sendo executado ou ocorrendo alguma falha.

A chamada manual do método System.gc() pode resultar em perda de performance, uma vez que ele utiliza recursos da JVM que estariam alocados na aplicação. Portanto é sugerido que a execução do GC seja feita de forma automática e controlada pela JVM.

Mas o que ocorre após os objetos estarem elegíveis para serem coletados pelo GC? Até a versão 1.9 do Java, o método Object.finalize era chamado antes dos objetos serem removidos fisicamente do Heap. Nas versões superiores ele foi marcado como @deprecated. Há um problema em relação a este método: não há garantia do momento de sua execução. Imagine que ele seja chamado para liberar algum recurso mas a aplicação terminar antes. O recurso ficará em execução ou aberto.

Esse post foi uma explicação do que o GC é, como funciona, quando e por quem é chamado. Além de apresentada uma armadilha na sua execução.

Em outros, retomarei a falar de memória e performance.

Até.

Fontes:

https://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html#gc()

https://www.udemy.com/course/java-application-performance-and-memory-management

https://pt.wikipedia.org/wiki/Coletor_de_lixo_(inform%C3%A1tica)

Leave a Reply

Your email address will not be published. Required fields are marked *