Garbage Collection Python x Java

Bruna Ferreira - Jul 1 '22 - - Dev Community

Introdução

Antes de partirmos para a coleta de lixo das linguagens, vamos entender um pouco como um programa é alocado na memória.

Quem faz o intermédio entre o programa e o hardware é o sistema operacional, ele quem vai fazer a tradução dos endereços lógicos gerados pela compilação de um programa para o endereço físico em um bloco de memória do computador.

Esse bloco é particionado, armazenando informações estáticas, de tamanho fixo, e deixando espaço para alocação dinâmica. Vejamos na imagem a seguir:

bloco de alocação de memória

Fixos

  • CÓDIGO - temos o armazenamento da sequência de instruções em código de máquina.
  • ESTÁTICO - aqui são guardadas as variáveis globais e estáticas, as quais precisam estar disponíveis durante toda execução do programa.

Dinâmicos

  • HEAP - esse espaço é destinado à alocação das variáveis dinâmicas e instâncias de objetos.
  • PILHA - na última partição são alocados os registros de ativação de uma função.

Nota-se que as duas últimas partições compartilham o mesmo espaço do bloco de memória.

A PILHA tem o início da sua alocação no final do bloco, crescendo de baixo para cima. Toda vez que uma função é concluída, ela é retirada do bloco automaticamente.

Enquanto o HEAP a alocação se dá no sentido oposto, desta forma o compartimento de alocação dinâmica é melhor aproveitado. É nesse particionamento que o coletor de lixo vai atuar.


Python

O python tem uma coleta de lixo automática, podem ser usadas duas estratégias:

Contagem de referência

Usada em versões anteriores a 2.0 do Python, baseada na contagem de vezes que um objeto é referenciado por outros objetos no sistema, onde a cada referência o contador é incrementado em +1 e quando a referência se perde, decrementamos -1. Quando o contador chega em zero, o objeto é desalocado.

Podem ocorrer referências cíclicas, onde os objetos não são atingidos de nenhuma maneira. Um modo fácil criar as referências cíclicas criando objetos que referenciam a si mesmos.

Coletor de lixo

Automático

O Python agenda a coleta de lixo automaticamente com base no seguinte cálculo: número de alocações - número de desalocações > número limite estabelecido.
Existe um módulo chamado gc que pode ser invocado para inspecionar esse limite.

gc.get_threshold()
Enter fullscreen mode Exit fullscreen mode

Manual

Para os casos de referência cíclicas, o gc tem uma função que pode coletar o lixo de forma manual

gc.collect()
Enter fullscreen mode Exit fullscreen mode

Java

O Java usa a estratégia de coleta de lixo parcial e total, funcionam da seguinte maneira:

O coletor de lixo é um processo automático, o qual examina a memória em busca de objetos que não estão sendo utilizados (sem referência do programa ao objeto) para fazer a exclusão dos mesmos.

O coletor é implementada na JVM e fica executando no background constantemente, podendo operar de duas maneiras:

  • Menor ou Incremental

Ocorre quando os objetos de 'geração nova' são alocados na memória e em seguida perdem a referência, ao examinar a memória, eles serão removidos.

  • Maior ou Total

Quando objetos sobrevivem à primeira coleta, esses são copiados para 'geração antiga ou permanente', estes são examinados com menos frequência.

Manual

Apesar da coleta de lixo ser automática, podemos tornar um objeto elegível para a remoção de forma manual, anulando o objeto (obj = null) ou criando objeto dentro de métodos, por exemplo. Também podemos solicitar à JVM a execução dos métodos gc para que remova esses objetos da memória mais rapidamente.

System.gc()
Enter fullscreen mode Exit fullscreen mode

Conclusão

A diferença principal notada é que o gc do Python é executado se baseando em um cálculo para verificar se chegou ao valor limite. Já no Java o gc é executado na JVM, examinando os objetos constantemente, em paralelo com a execução do programa.


Referência Python

Referência Java

. . . . . . . . . . . . . .