CodeGym /Blogue Java /Random-PT /Mais sobre o coletor de lixo
John Squirrels
Nível 41
San Francisco

Mais sobre o coletor de lixo

Publicado no grupo Random-PT
Oi! Na última lição, nos familiarizamos com o coletor de lixo interno do Java e tivemos uma ideia aproximada de como ele funciona. Ele funciona em segundo plano enquanto seu programa está rodando, coletando objetos desnecessários que serão apagados posteriormente. Assim, libera memória que pode ser usada para criar novos objetos no futuro.
Mais sobre o coletor de lixo - 1
Nesta lição, discutiremos com mais detalhes como isso funciona. Por exemplo, como e quando um objeto se torna desnecessário? E como o coletor de lixo descobre? Estas são perguntas que responderemos durante a lição de hoje :) A lição será mais como uma visão geral: você não precisa decorar este material. A intenção é principalmente expandir sua visão sobre como a memória e o coletor de lixo funcionam, então apenas leia e encontre algo novo para você :) Vamos lá! A primeira coisa que você precisa lembrar é que o coletor de lixo funciona em paralelo com o seu programa. Não faz parte do seu programa. Ele funciona separadamente (na última lição, comparamos isso com um aspirador de pó robô) Mas nem sempre foi assim. A coleta de lixo costumava ser realizada no mesmo thread do seu programa. Em algum horário (uma vez a cada poucos minutos), o coletor de lixo verificaria a presença de objetos indesejados no programa. O problema era que o programa travava (não executava) durante essa verificação e coleta de lixo. Imagine que você está sentado em seu escritório no trabalho. Mas então a faxineira entra para lavar o chão. Ela afasta você do computador por 5 minutos e você espera até que ela termine de limpar. Durante esse tempo, você não pode trabalhar. É mais ou menos assim que a coleta de lixo costumava funcionar :) Esse mecanismo foi alterado posteriormente e agora o coletor de lixo é executado em segundo plano, não impedindo o trabalho do próprio programa. Você já sabe que um objeto morre quando não tem mais referências. Na realidade,o coletor de lixo não conta referências de objeto . Primeiro, isso pode levar muito tempo. Em segundo lugar, não é muito eficaz. Afinal, os objetos podem se referir uns aos outros! Mais sobre o coletor de lixo - 2A figura mostra um exemplo onde 3 objetos se referem uns aos outros, mas ninguém mais se refere a eles. Em outras palavras, o restante do programa não precisa deles. Se o coletor de lixo simplesmente contasse as referências, esses 3 objetos não seriam coletados e a memória não seria liberada (existem referências a eles!). Podemos comparar isso a uma espaçonave. Durante o voo, os astronautas decidem verificar a lista de peças de reposição disponíveis para reparos. Entre outras coisas, eles encontram um volante e pedais de um carro comum. Obviamente, eles não são necessários aqui e estão ocupando espaço desnecessariamente (embora essas duas partes estejam relacionadas entre si e tenham algumas funções). Mas dentro da espaçonave, são lixos inúteis que devem ser descartados. Assim, em Java, foi tomada a decisão de coletar lixo não com base na contagem de referência,alcançáveis ​​e inalcançáveis . Como determinamos se um objeto é alcançável? É tudo simplesmente engenhoso. Um objeto é alcançável se for referenciado por outro objeto alcançável. Assim, obtemos uma "cadeia de acessibilidade". Começa quando o programa começa e continua durante o programa. É mais ou menos assim: Mais sobre o coletor de lixo - 3 A seta na figura indica o código executável do nosso programa. O código (por exemplo, o main()método) cria referências a objetos. Esses objetos podem referir-se a outros objetos, esses objetos a outros ainda, e assim por diante. Isso forma uma cadeia de referência. Se você puder rastrear a cadeia de um objeto até a "referência raiz" (aquela criada diretamente no código executável), ela será considerada alcançável. Esses objetos são marcados em preto na imagem. Mas um objeto é inacessível se o objeto sair dessa cadeia, ou seja, nenhuma das variáveis ​​no código que está sendo executado faz referência a ele e não pode ser alcançado por meio da "cadeia de referência". Em nosso programa, dois desses objetos são marcados em vermelho. Observe que esses objetos "vermelhos" têm referências uns aos outros. Mas, como dissemos anteriormente, o coletor de lixo moderno de Java não conta referências. Determina se um objeto é alcançável ou inacessível. Como resultado, ele se apoderará dos dois objetos vermelhos da figura. Agora vamos ver todo o processo do começo ao fim. Ao fazer isso, também veremos como a memória é organizada em Java :) Todos os objetos Java são armazenados em uma área especial da memória chamada heap . Na linguagem do dia-a-dia, um amontoado costuma ser uma montanha de itens, onde tudo se mistura. Mas não é isso que o heap é em Java. Sua estrutura é muito lógica e razoável. Em algum momento, os programadores Java descobriram que todos os seus objetos poderiam ser divididos em dois tipos: objetos simples e "objetos de vida longa".. "Objetos de vida longa" são objetos que sobreviveram a muitas rodadas de coleta de lixo. Eles geralmente vivem até o fim do programa. No final, a pilha completa, onde todos os objetos são armazenados, foi dividida em várias partes. A primeira parte tem um lindo nome: eden(do "Jardim do Éden" bíblico). Este nome é apropriado, porque é onde os objetos terminam após serem criados. Esta é a parte da memória onde novos objetos são criados quando usamos a palavra-chave new. Muitos objetos podem ser criados. Quando essa área fica sem espaço, uma coleta de lixo inicial "rápida" começa. Devemos dizer que o coletor de lixo é muito inteligente. Ele escolhe um algoritmo com base em se o heap tem mais lixo ou mais objetos ativos. Se quase todos os objetos forem lixo, o coletor marca os objetos vivos e os move para outra área da memória. Então a área atual é completamente limpa. Se não houver muito lixo e a pilha for composta principalmente de objetos vivos, o coletor marca o lixo, limpa-o e junta os outros objetos. Nós dissemos "um espaço de sobrevivência . Um espaço de sobrevivência , por sua vez, é dividido em gerações . Cada objeto pertence a uma geração específica, dependendo de quantas rodadas de coleta de lixo ele sobreviveu. Se um objeto sobreviveu a uma rodada de coleta de lixo, ele está na "Geração 1"; se 5, então "Geração 5". Juntos, o éden e um espaço de sobrevivência formam uma área chamada geração jovem . Além da geração jovem, a pilha possui outra área de memória chamada geração antiga. Esta é precisamente a área onde terminam os objetos de vida longa que sobreviveram a muitas rodadas de coleta de lixo. Há vantagens em mantê-los separados de todos os outros. A coleta de lixo completa é executada apenas quando a geração antiga está cheia, ou seja, há tantos objetos de vida longa no programa que não há memória suficiente. Esse processo envolve mais de uma área da memória. Em geral, envolve todos os objetos criados pela máquina Java. Naturalmente, isso leva muito mais tempo e recursos. Esta é precisamente a decisão tomada para armazenar objetos de vida longa separadamente. A "coleta rápida de lixo" é realizada quando outras áreas ficam sem espaço. Isso envolve apenas uma área, o que a torna mais rápida e eficiente. Finalmente, quando até mesmo a área para objetos de vida longa é completamente preenchida, coleta de lixo completa é acionada. Assim, o coletor usa a ferramenta "mais pesada" apenas quando é impossível evitá-la. Aqui está uma representação visual da estrutura de heap e coleta de lixo: Mais sobre o coletor de lixo - 4
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION