O que é o coletor de lixo em Java?

103

Eu sou novo em Java e estou confuso sobre o coletor de lixo em Java. O que realmente faz e quando entra em ação. Descreva algumas das propriedades do coletor de lixo em Java.

Subhransu Mishra
fonte
2
possível duplicata da Coleta
Ian Ringrose
10
Às vezes, é melhor ler o capítulo de um bom livro e esperar entender um assunto complexo a partir da resposta a uma pergunta.
Ian Ringrose
4
@Ian É uma pergunta semelhante, mas não uma duplicata. E essa pergunta cheira a dever de casa.
NullUserException

Respostas:

119

O coletor de lixo é um programa executado na máquina virtual Java que remove objetos que não estão mais sendo usados ​​por um aplicativo Java. É uma forma de gerenciamento automático de memória .

Quando uma aplicação típica Java é executado, ele está criando novos objetos, como Strings e Files, mas depois de um certo tempo, esses objetos não são mais utilizados. Por exemplo, dê uma olhada no seguinte código:

for (File f : files) {
    String s = f.getName();
}

No código acima, o String sestá sendo criado em cada iteração do forloop. Isso significa que a cada iteração, um pouco de memória está sendo alocada para fazer um Stringobjeto.

Voltando ao código, podemos ver que uma vez executada uma única iteração, na próxima iteração, o Stringobjeto que foi criado na iteração anterior não está mais sendo usado - esse objeto agora é considerado "lixo".

Eventualmente, começaremos a receber muito lixo e a memória será usada para objetos que não estão mais sendo usados. Se isso continuar acontecendo, eventualmente a Java Virtual Machine ficará sem espaço para fazer novos objetos.

É aí que entra o coletor de lixo.

O coletor de lixo irá procurar por objetos que não estão mais sendo usados ​​e se livrar deles, liberando a memória para que outros novos objetos possam usar aquele pedaço de memória.

Em Java, o gerenciamento de memória é feito pelo coletor de lixo, mas em outras linguagens como C, é necessário realizar o gerenciamento de memória por conta própria usando funções como mallocefree . O gerenciamento de memória é uma daquelas coisas que são fáceis de cometer erros, o que pode levar ao que chamamos de vazamentos de memória - lugares onde a memória não é recuperada quando não está mais em uso.

Esquemas de gerenciamento automático de memória, como coleta de lixo, fazem com que o programador não precise se preocupar tanto com problemas de gerenciamento de memória, para que ele possa se concentrar mais no desenvolvimento dos aplicativos que precisam desenvolver.

coobird
fonte
Seria verdade dizer que um aplicativo Java em execução em um computador tem duas funcionalidades de coleta de lixo? Um com a máquina virtual Java. E então um na máquina real que executa o Windows? (Ou qualquer outro sistema operacional)
Lealo
Não, geralmente os aplicativos Java são executados apenas se o JRE estiver presente. Portanto, apenas a funcionalidade de coleta de lixo da JVM é necessária! @Lealo
Am_I_Helpful
18

Ele libera memória alocada para objetos que não estão mais sendo usados ​​pelo programa - daí o nome "lixo". Por exemplo:

public static Object otherMethod(Object obj) {
    return new Object();
}

public static void main(String[] args) {
    Object myObj = new Object();
    myObj = otherMethod(myObj);
    // ... more code ...  
}

Eu sei que isso é extremamente artificial, mas aqui, depois de você chamar, otherMethod()o original Objectcriado torna-se inacessível - e isso é "lixo" que é coletado.

Em Java, o GC é executado automaticamente, mas você também pode chamá-lo explicitamente com System.gc()e tentar forçar uma grande coleta de lixo. Como Pascal Thivent aponta, você realmente não deveria ter que fazer isso e pode fazer mais mal do que bem (veja esta pergunta ).

Para obter mais informações, consulte a entrada da wikipedia em Garbage collection e Tuning Garbage Collection (do Oracle)

NullUserException
fonte
1
AFAIK System.gc()não força o GC a funcionar.
Itay Karo
1
1 para o bom exemplo de código. Observe que é perfeitamente válido para o GC destruir myObjantes da chamada de otherMethodocorrer, porque myObjnão está mais acessível nesse ponto.
Billy ONeal
@Italy, acredito que seja específico da implementação.
NullUserException
2
Acho que não se deve ligar System.gc(), o objetivo de ter um CG é não ter que fazer isso.
Pascal Thivent
com a análise de escape ( en.wikipedia.org/wiki/Escape_analysis ), é possível que a JVM nem mesmo aloque o objeto em primeiro lugar neste exemplo. Toda a criação do objeto pode (em teoria) ser otimizada. Depende da implementação, é claro.
Mikera de
15

Um objeto se torna elegível para a coleta de lixo ou GC se não for alcançável de nenhum encadeamento ativo ou por qualquer referência estática.

Em outras palavras, você pode dizer que um objeto se torna elegível para a coleta de lixo se todas as suas referências forem nulas. Dependências cíclicas não são contadas como a referência, portanto, se o objeto A tiver uma referência ao objeto B e o objeto B tiver uma referência ao objeto A e eles não tiverem nenhuma outra referência ativa, os objetos A e B serão elegíveis para a coleta de lixo.


Gerações de heap para coleta de lixo -

Os objetos Java são criados Heape Heapdivididos em três partes ou gerações para fins de coleta de lixo em Java, são chamados de geração jovem (nova), geração antiga (antiga) e área permanente do heap.

Java Heap Space A Nova Geração é dividida em três partes conhecidas como espaço Eden, espaço Survivor 1 e espaço Survivor 2. Quando um objeto criado no heap, ele é criado na nova geração dentro do espaço do Éden e após a coleta de lixo secundária subsequente, se um objeto sobreviver, ele é movido para o sobrevivente 1 e o sobrevivente 2 antes que a coleta de lixo principal mova esse objeto para a geração antiga ou estável .

O espaço permanente do Java Heap é onde a JVM armazena metadados sobre classes e métodos, conjunto de strings e detalhes de nível de classe.

Gerações de heap para coleta de lixo

Consulte aqui para mais informações: Coleta de lixo


Você não pode forçar a JVM a executar a Coleta de Lixo, embora possa fazer uma solicitação usando o método System.gc()ou Runtime.gc().

Em java.lang.System

public static void gc() {
    Runtime.getRuntime().gc();  
}

Em java.lang.Runtime

public native void gc();  // note native  method

Algoritmo de marcação e varredura -

Este é um dos algoritmos mais populares usados ​​pela coleta de lixo. Qualquer algoritmo de coleta de lixo deve realizar 2 operações básicas. Em primeiro lugar, ele deve ser capaz de detectar todos os objetos inacessíveis e, em segundo lugar, deve recuperar o espaço de heap usado pelos objetos de lixo e disponibilizar o espaço novamente para o programa.

As operações acima são realizadas por Mark and Sweep Algorithm em duas fases:

  1. Fase de marca
  2. Fase de varredura

leia aqui para mais detalhes - Mark and Sweep Algorithm

roottraveller
fonte
6

coletor de lixo implica que os objetos que não são mais necessários para o programa são "lixo" e podem ser jogados fora.

Nik
fonte
6

O Garbage Collector é parte do JRE que garante que o objeto não referenciado seja liberado da memória.
Geralmente é executado quando o aplicativo fica sem memória. AFAIK contém um gráfico que representa as ligações entre os objetos e os objetos isolados podem ser liberados.
Para salvar o desempenho dos objetos atuais agrupados em gerações, cada vez que o GC verifica um objeto e descobre que ele ainda está referenciado, sua contagem de geração incrementada em 1 (para algum valor máximo máximo, 3 ou 4, eu acho), e a nova geração é verificada primeiro (quanto mais curto o objeto na memória, maior a probabilidade de ele não ser mais necessário), portanto, nem todos os objetos são verificados sempre que o GC é executado.
leia isto para mais informações.

Itay Karo
fonte
@quantumSoup você é positivo nisso? Acredito que algum tipo de coleta de lixo (mais caro) só acontece quando o heap se enche.
Pablo Fernandez
2
@quantumSoup - isso depende da implementação do GC do JRE. Em muitos casos, o GC não funciona constantemente. Em vez disso, ele é executado quando seu aplicativo não consegue alocar um objeto porque o heap está cheio. JVMs HotSpot recentes incluem um GC paralelo, mas não é habilitado por padrão.
Stephen C
Essa resposta concentra-se muito no mecanismo. A pergunta era "O que é o coletor de lixo", não "Como funciona o coletor de lixo"
Billy ONeal
@quantum: neutralizou o seu -1, porque: Aprender, ou seja, para que serve esta página, certo? Para aprender, você precisa cometer erros. Punir os erros faz com que as pessoas não aprendam. Espero que você possa concordar nesse ponto. E talvez você tenha cometido um erro aqui.
erikbwork
1
@erikb: Por essa lógica, nunca haveria nenhum downvotes. E votos negativos são necessários para eliminar respostas relativamente ruins. O OP é obviamente um iniciante, e o funcionamento interno específico do GC simplesmente não é importante para a pergunta feita. Uma vez que esta resposta não responde à pergunta feita (responde a outra), os votos negativos são perfeitamente justificados.
Billy ONeal
3

O coletor de lixo permite que seu computador simule um computador com memória infinita. O resto é apenas mecanismo.

Ele faz isso detectando quando pedaços de memória não estão mais acessíveis a partir do seu código e retornando esses pedaços para o armazenamento gratuito.

EDIT: Sim, o link é para C #, mas C # e Java são idênticos a esse respeito.

Billy ONeal
fonte
Na verdade, há uma pergunta no SO sobre a diferença entre java e C # 's GC: stackoverflow.com/questions/492703/c-vs-java-garbage-collector
NullUserException
3

Muitas pessoas pensam que a coleta de lixo coleta e descarta objetos mortos.
Na realidade, a coleta de lixo Java está fazendo o oposto! Objetos vivos são rastreados e tudo o mais é designado como lixo.

Quando um objeto não é mais usado, o coletor de lixo recupera a memória subjacente e a reutiliza para futura alocação de objeto. Isso significa que não há exclusão explícita e nenhuma memória é devolvida ao sistema operacional. Para determinar quais objetos não estão mais em uso, a JVM executa de forma intermitente o que é muito apropriadamente chamado de algoritmo de marcação e varredura.

Verifique isso para obter mais informações detalhadas: http://javabook.compuware.com/content/memory/how-garbage-collection-works.aspx

VdeX
fonte
1

Para colocá-lo nos termos mais simples que até mesmo um não-programador pode entender, quando um programa processa dados, ele cria dados intermediários e espaço de armazenamento (variáveis, matrizes, certos metadados de objetos etc.) para esses dados.

Quando esses objetos são acessados ​​por meio de funções ou sobre um determinado tamanho, eles são alocados a partir de um heap central. Então, quando eles não forem mais necessários, eles precisam ser limpos.

Existem alguns artigos online muito bons sobre como isso funciona, então cobrirei apenas a definição básica.

O GC é basicamente a função que faz essa limpeza. Fazer isso limpa as entradas da tabela que não são referenciadas por nenhum objeto ativo, excluindo efetivamente os objetos, depois copia e compacta a memória. É um pouco mais complicado do que isso, mas essa é a ideia.

O grande problema é que algumas partes desse processo geralmente exigem que todo o Java VM seja interrompido temporariamente para ocorrer, bem como todo esse processo exige muito do processador e da largura de banda da memória. As várias opções de GCs e opções de ajuste para cada um são projetadas para equilibrar esses vários problemas com todo o processo de GC.

Robert Wm Ruedisueli
fonte
0

A coleta de lixo em Java (e outras linguagens / plataformas também) é uma maneira do ambiente de tempo de execução java (JRE) reutilizar a memória de objetos java que não são mais necessários. De forma simplista, quando o JRE é inicializado pela primeira vez, ele solicita ao Sistema Operacional (O / S) uma certa quantidade de memória. Conforme o JRE executa seu (s) aplicativo (s), ele usa essa memória. Quando seu aplicativo termina de usar essa memória, o "Coletor de lixo" do JRE vem e recupera essa memória para uso por diferentes partes de seu (s) aplicativo (s) existente (s). O "Coletor de lixo" do JRE é uma tarefa em segundo plano que está sempre em execução e tenta selecionar os horários em que o sistema está ocioso para realizar suas execuções de lixo.

Uma analogia do mundo real seria com os lixeiros que vão até sua casa e pegam seu lixo reciclável ... eventualmente, ele é reutilizado de outras formas por você e / ou outras pessoas.

Al Dass
fonte
0

O coletor de lixo pode ser visto como um gerenciador de contagem de referência. se um objeto é criado e sua referência é armazenada em uma variável, sua contagem de referência é aumentada em um. durante o curso da execução se essa variável for atribuída com NULL. a contagem de referência para esse objeto é diminuída. portanto, a contagem de referência atual para o objeto é 0. Agora, quando o coletor de lixo é executado, ele verifica os objetos com contagem de referência 0. e libera os recursos alocados para ele.

A invocação do coletor de lixo é controlada por políticas de coleta de lixo.

Você pode obter alguns dados aqui. http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html

Bala Sreekanth
fonte
1
A contagem de referência é uma péssima maneira de implementar GC. Eu não acho que nenhuma implementação JVM principal use isso.
NullUserException
0

O coletor de lixo é um componente do jvm.

Ele é usado para coletar lixo sempre que a CPU fica livre.

Aqui lixo significa objetos não usados ​​que ele roda no plano de fundo do programa principal

para monitorar o status do programa principal.

Pulipati Prasadarao
fonte
0

A coleta de lixo automática é o processo de examinar a memória heap, identificando quais objetos estão em uso e quais não estão, e excluindo os objetos não utilizados. Um objeto em uso, ou um objeto referenciado, significa que alguma parte do seu programa ainda mantém um ponteiro para esse objeto. Um objeto não utilizado, ou objeto não referenciado, não é mais referenciado por qualquer parte de seu programa. Portanto, a memória usada por um objeto não referenciado pode ser recuperada.

Em uma linguagem de programação como C, alocar e desalocar memória é um processo manual. Em Java, o processo de desalocação de memória é tratado automaticamente pelo coletor de lixo. Por favor, verifique o link para um melhor entendimento. http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html

Shashank Shankaranand
fonte
0

A coleta de lixo se refere ao processo de liberação automática de memória no heap, excluindo objetos que não são mais acessíveis em seu programa. O heap é uma memória referida como armazenamento gratuito e representa um grande conjunto de memória não utilizada alocada para seu aplicativo Java.

Aamir M Meman
fonte
1
Não use formatação de citação para texto que não está citado e, se for citado, você precisa citar a fonte.
Marquês de Lorne,
0

Os princípios básicos da coleta de lixo são localizar objetos de dados em um programa que não pode ser acessado no futuro e recuperar os recursos usados ​​por esses objetos. https://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29

Vantagens

1) Salva de bugs, que ocorrem quando um pedaço de memória é liberado enquanto ainda há ponteiros para ele, e um desses ponteiros é desreferenciado. https://en.wikipedia.org/wiki/Dangling_pointer

2) Double free bugs, que ocorrem quando o programa tenta liberar uma região da memória que já foi liberada, e talvez já tenha sido alocada novamente.

3) Previne certos tipos de vazamentos de memória, nos quais um programa falha em liberar memória ocupada por objetos que se tornaram inacessíveis, o que pode levar ao esgotamento da memória.

Desvantagens

1) Consumir recursos adicionais, impactos no desempenho, possíveis paralisações na execução do programa e incompatibilidade com o gerenciamento manual de recursos. A coleta de lixo consome recursos de computação ao decidir qual memória liberar, embora o programador já possa ter conhecido essa informação.

2) O momento em que o lixo é realmente coletado pode ser imprevisível, resultando em paralisações (pausas para trocar / liberar memória) espalhadas por toda a sessão. Paradas imprevisíveis podem ser inaceitáveis ​​em ambientes de tempo real, no processamento de transações ou em programas interativos.


Tutorial da Oracle http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html

A coleta de lixo é o processo que identifica quais objetos estão em uso e quais não estão, e exclui os objetos não usados.

Em linguagens de programação como C, C ++, alocar e liberar memória é um processo manual.

int * array = new int[size];
processArray(array); //do some work.
delete array; //Free memory

A primeira etapa do processo é chamada de marcação. É aqui que o coletor de lixo identifica quais partes da memória estão em uso e quais não estão.

Etapa 2a. A exclusão normal remove objetos não referenciados, deixando objetos referenciados e ponteiros para espaço livre.

Para melhorar o desempenho, queremos excluir objetos não referenciados e também compactar os objetos referenciados restantes. Queremos manter os objetos referenciados juntos, então será mais rápido alocar nova memória.

Conforme declarado anteriormente, ter que marcar e compactar todos os objetos em uma JVM é ineficiente. À medida que mais e mais objetos são alocados, a lista de objetos aumenta cada vez mais, levando a um tempo cada vez mais longo de coleta de lixo.

Continue lendo este tutorial e você saberá como o GC enfrenta esse desafio.

Resumindo, existem três regiões do heap, YoungGeneration para objetos de curta duração, OldGeneration para objetos de longo período e PermanentGeneration para objetos que vivem durante a vida do aplicativo, por exemplo, classes, bibliotecas.

Yan Khonski
fonte
0

Como os objetos são alocados dinamicamente pelo novo operador, você pode perguntar como esses objetos são destruídos e como a memória ocupada é liberada. Em outras linguagens, como C ++, você precisa liberar objetos alocados manualmente de forma dinâmica pelo operador delete. Java tem uma abordagem diferente; ele lida automaticamente com a desalocação. A técnica é conhecida como Coleta de Lixo .

Funciona assim: quando não há referências a um objeto, assume-se que esse objeto não é mais necessário e você pode recuperar a memória ocupada pelo objeto. Não é necessário destruir explicitamente os objetos como em C ++. A coleta de lixo ocorre esporadicamente durante a execução do programa; Isso não acontece simplesmente porque há um ou mais objetos que não são mais usados. Além disso, várias implementações de tempo de execução Java têm diferentes abordagens para a coleta de lixo, mas a maioria dos programadores não precisa se preocupar com isso ao escrever programas.

Amarildo
fonte
-2

A coleta de lixo automática é um processo em que a JVM se livra de ou mantém certos pontos de dados na memória para liberar espaço para o programa em execução. A memória é enviada primeiro para a memória heap, que é onde o coletor de lixo (GC) faz seu trabalho e, em seguida, é decidido que será encerrado ou mantido. Java assume que nem sempre se pode confiar no programador, portanto, ele encerra os itens que acha que não precisa.

Lopes_CP_2579
fonte