CodeGym /Blogue Java /Random-PT /Ciclo de vida do objeto
John Squirrels
Nível 41
San Francisco

Ciclo de vida do objeto

Publicado no grupo Random-PT
Oi! Acho que você não ficaria muito surpreso se eu dissesse que seu computador tem uma quantidade limitada de memória :)
Ciclo de vida do objeto - 1
Até mesmo seu disco rígido (que é muitas, muitas vezes o tamanho da RAM) pode ficar cheio de seus jogos favoritos, programas de TV e outras coisas. Para evitar que isso aconteça, você precisa monitorar o estado atual da memória do seu computador e excluir arquivos desnecessários. Como tudo isso se relaciona com a programação Java? Muito diretamente! Afinal, criar qualquer objeto faz com que a máquina Java aloque memória para ele . Um grande programa do mundo real cria dezenas ou centenas de milhares de objetos, e um pedaço de memória é alocado para cada um deles. Mas o que você acha, quantos desses objetos existem? Eles estão "vivos" o tempo todo enquanto nosso programa está em execução? Claro que não. Mesmo com todas as suas vantagens, os objetos Java não são imortais :) Os objetos têm seu próprio ciclo de vida. Hoje vamos fazer uma pequena pausa na escrita de código e explorar esse processo :) Também é muito importante para entender como um programa funciona e para gerenciar recursos. Então, onde começa a vida de um objeto? Como um ser humano, desde o nascimento, ou seja, quando é criado.

Cat cat = new Cat();// Our Cat object's lifecycle begins now!
Primeiro, a máquina virtual Java aloca a memória necessária para criar o objeto. Em seguida, ele cria uma referência a ele (no nosso caso, cat) para possibilitar o acompanhamento. Em seguida, todas as variáveis ​​são inicializadas, o construtor é chamado e nosso novo objeto agora está vivendo sua própria vida :) O tempo de vida do objeto varia. Não há números exatos aqui. De qualquer forma, um objeto vive no programa e desempenha suas funções por algum período de tempo. Para ser preciso, o objeto está "vivo" enquanto houver referências a ele. Assim que não houver referências, o objeto "morre". Por exemplo:

public class Car {
  
   String model;

   public Car(String model) {
       this.model = model;
   }

   public static void main(String[] args) {
       Car lamborghini  = new Car("Lamborghini Diablo");
       lamborghini = null;

   }

}
No main()método, o objeto Car "Lamborghini Diablo" deixa de estar vivo na segunda linha. Havia apenas uma referência a ele e a referência foi definida como nula. Como não há referências restantes ao Diablo, ele se torna "lixo". Uma referência não precisa ser definida como zero para que isso aconteça:

public class Car {

   String model;

   public Car(String model) {
       this.model = model;
   }

   public static void main(String[] args) {
       Car lamborghini  = new Car("Lamborghini Diablo");

       Car lamborghiniGallardo = new Car("Lamborghini Gallardo");
       lamborghini = lamborghiniGallardo;
   }

}
Aqui criamos um segundo objeto e o atribuímos à referência lamborghini. Agora, duas referências apontam para o Lamborghini Gallardoobjeto, mas o Lamborghini Diabloobjeto não tem nenhuma. Isso significa que o Diabloobjeto se torna lixo. É quando o coletor de lixo (GC) integrado do Java entra em ação.
Ciclo de vida do objeto - 2
O coletor de lixo é um mecanismo interno do Java responsável por liberar memória, ou seja, remover objetos desnecessários da memória. Há uma razão pela qual escolhemos representá-lo com um aspirador de pó robô. O coletor de lixo funciona mais ou menos da mesma maneira: ele "move" seu programa em segundo plano, coletando lixo. Você praticamente não precisa interagir com ele. Sua função é deletar objetos que não são mais usados ​​no programa. Assim, libera memória para outros objetos. Você se lembra que no início da aula dissemos que na vida real você deve monitorar o estado do seu computador e deletar arquivos antigos? Se estamos falando de objetos Java, o coletor de lixo faz isso para você. O coletor de lixo é iniciado várias vezes enquanto seu programa é executado: você não precisa chamá-lo explicitamente e dar comandos (embora isso seja tecnicamente possível). Falaremos mais sobre o coletor de lixo mais adiante e analisaremos com mais detalhes como ele funciona. Quando o coletor de lixo atinge um objeto - pouco antes de ser destruído - o finalize()método especial do objeto é chamado. Este método pode ser invocado para liberar certos recursos adicionais usados ​​pelo objeto. O finalize()método pertence à classe Object. Em outras palavras, é semelhante a equals(), hashCode()e toString()(que você conheceu anteriormente). Todo objeto tem isso . Ele difere de outros métodos porque... como devemos dizer isso... é muito obstinado. Com isso queremos dizer quenem sempre é chamado antes de um objeto ser destruído . A programação é uma atividade muito precisa. O programador diz ao computador para fazer algo, e o computador faz. Presumo que você esteja acostumado a esse tipo de comportamento, então, a princípio, pode ser difícil para você aceitar a seguinte ideia: "Antes de um objeto ser destruído, o método da classe Object é chamado. Ou não. finalize()Se tivermos sorte! " Ainda assim, esta é a realidade. A própria máquina Java determina se deve chamar finalize() caso a caso. Como experiência, vamos tentar executar o seguinte código:

public class Cat {

   private String name;

   public Cat(String name) {
       this.name = name;
   }

   public Cat() {
   }

   public static void main(String[] args) throws Throwable {

       for (int i = 0 ; i < 1000000; i++) {

           Cat cat = new Cat();
           cat = null;// The first object becomes available for garbage collection here
       }
   }

   @Override
   protected void finalize() throws Throwable {
       System.out.println("The Cat is destroyed!");
   }
}
Criamos um Catobjeto e na próxima linha zeramos a única referência a ele. E fazemos isso um milhão de vezes. Substituímos explicitamente o finalize()método. Cada vez que um Catobjeto é destruído, ele deve exibir uma string – um total de um milhão de vezes. Mas não! Para ser exato, no meu computador foi executado apenas 37346 vezes! Em outras palavras, minha máquina Java decidiu chamar o finalize()método em apenas 1 de cada 27 casos. Nos demais casos, a coleta de lixo não envolvia essa chamada. Tente executar este código você mesmo. Você provavelmente obterá um resultado diferente. Como você pode ver, é difícil chamar finalize()um parceiro confiável :) Então, aqui vai uma pequena dica para o futuro: não confie no finalize()método para liberar recursos críticos.A JVM pode chamá-lo ou não. Quem sabe? Se seu objeto manteve alguns recursos críticos de desempenho (por exemplo, uma conexão de banco de dados aberta) enquanto estava ativo, seria melhor criar e chamar explicitamente um método especial para liberá-los quando o objeto não for mais necessário. Dessa forma, você terá certeza de que o desempenho do seu programa não será prejudicado. Começamos dizendo que trabalhar com memória e coleta de lixo são tópicos muito importantes, e de fato são. O manuseio incorreto de recursos e a má compreensão de como os objetos desnecessários são limpos podem levar a um dos erros mais desagradáveis: vazamentos de memória . Este é um dos erros de programação mais conhecidos. Ele ainda tem seu próprio artigo da Wikipedia. Código mal escrito pode criar uma situação em que a memória é sempre alocada para objetos recém-criados, mas objetos antigos e desnecessários ficam indisponíveis para coleta de lixo. Como já fizemos a analogia do robô aspirador de pó, imagine o que aconteceria se antes de executar o robô você espalhasse meias pela casa toda, quebrasse um vaso de vidro e deixasse peças de Lego espalhadas pelo chão. Naturalmente, o robô tentaria fazer alguma coisa, mas um dia travaria.
Ciclo de vida do objeto - 3
Para que o aspirador funcione bem, é preciso manter o chão em bom estado e recolher tudo o que ele não aguenta. O coletor de lixo segue o mesmo princípio. Se um programa tiver muitos objetos que não pode limpar (como uma meia ou Lego para nosso aspirador de pó robótico), um dia ficaremos sem memória. Não apenas o seu programa travará, mas também todos os outros programas que estiverem em execução no computador. Afinal, eles também não terão memória suficiente (voltando à nossa analogia, o vidro quebrado no chão para não só o aspirador, mas também as pessoas que moram na casa). Resumindo, é assim que o ciclo de vida do objeto e a coleta de lixo se parecem em Java. Você não precisa memorizar isso: basta simplesmente entender como funciona. Na próxima lição, nós Voltarei a esses processos com mais detalhes. Mas, por enquanto, você pode voltar a resolver as tarefas do CodeGym :) Boa sorte!
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION