Prefácio
Vi uma pergunta no SegmentFault: Java tem um mecanismo GC completo, então haverá um problema de vazamento de memória em Java e posso dar um caso de vazamento de memória. Esta visão da pergunta fornece a resposta completa a esta pergunta.
Introdução ao mecanismo de reciclagem de lixo
Durante o programa em execução, cada objeto é criado, uma certa quantidade de memória é alocada para armazenar dados do objeto. Se você continuar alocando a memória, o programa enfrentará o problema da memória insuficiente mais cedo ou mais tarde. Portanto, em qualquer idioma, haverá um mecanismo de recuperação de memória para liberar a memória dos objetos vencidos para garantir que a memória possa ser reutilizada.
O mecanismo de reciclagem de memória pode ser dividido em dois tipos de acordo com as funções de implementação. Uma é que os programadores percebem manualmente o lançamento da memória (como a linguagem C) e o outro é o mecanismo de reciclagem de memória interno do idioma, como o mecanismo de coleta de lixo Java a ser introduzido neste artigo.
Mecanismo de coleta de lixo de Java
No ambiente de tempo de execução do programa, o Java Virtual Machine fornece um thread de coleta de lixo no nível do sistema (GC, Carbage Collection), responsável por recuperar a memória ocupada por objetos que perderam referências. O pré -requisito para entender o GC é entender alguns conceitos relacionados à coleta de lixo. Esses conceitos são introduzidos um a um a seguir.
O estado do objeto na área da pilha da JVM
Instâncias de objetos Java são armazenadas na área de heap da JVM. Para tópicos GC, esses objetos têm três estados.
1. Estado tocável: existem referências variáveis no programa, portanto esse objeto é tocável no estado.
2. Estado reativado: quando nenhuma variável no programa se referir a esse objeto, o objeto mudará de um estado tocável para um estado reativado. O thread CG se preparará para chamar o método finalizado desse objeto em um determinado momento (o método finalizado herda ou reescreve o objeto filho). O código no método Finalize pode converter o objeto em um estado tocável, caso contrário, o objeto será convertido em um estado intocável.
3. Estado intocável: o thread GC pode reciclar a memória desse objeto somente quando o objeto está em um estado intocável.
Para liberar corretamente os objetos, o GC deve monitorar o status de execução de cada objeto, incluindo o aplicativo, citação, citação, atribuição etc. O GC precisa monitorá -lo, para que o GC saberá, independentemente de um objeto estar em algum estado acima.
Como mencionado acima, os threads GC executarão o método finalizado de objetos de estado ressuscível em um determinado momento. Então, quando será executado? Como diferentes implementadores da JVM podem usar algoritmos diferentes para gerenciar o GC, a qualquer momento, os desenvolvedores não podem prever o momento dos threads GC que executam várias operações (incluindo a detecção do estado do objeto, a liberação da memória do objeto e da chamada de objetos de chamada). Embora o thread GC possa ser lembrado de executar operações de coleta de lixo o mais rápido possível através das funções System.GC () e Runtime.GC (), isso não pode garantir que o Thread GC execute operações de reciclagem correspondentes imediatamente.
Vazamento de memória
Os vazamentos de memória são causados por designs errados que o programa não libera a memória que não é mais usada, resultando em desperdício de recursos. O GC limpará automaticamente a memória ocupada por objetos que perderam referências. No entanto, se alguns objetos forem sempre referenciados devido a erros de programação, ocorrerá um vazamento de memória.
Por exemplo, o exemplo a seguir. Uma matriz é usada para implementar uma pilha, com duas operações: entrada de pilha e saída de pilha.
importar com.sun.javafx.collection.ElementObServableListDecorator; importar com.sun.swing.internal.plaf.metal.resources.metal_sv; import java.beans.excectListener; importar java.util.emptStAckexception; */public class MyStack {Private Object [] Elements; private int increment = 10; private int tamanho = 0; public myStack (int size) {elementos = novo objeto [size]; } // Coloque a pilha de vazio pública (objeto o) {Capacate (); elementos [tamanho ++] = O; } // Coloque o objeto público da pilha pop () {if (size == 0) lança new emptyStackStackSception (); Retornar elementos [-tamanho]; } // Aumente a capacidade da capacidade de vazio privado da pilha () {if (elements.Length! = Size) retornar; Objeto [] newArray = novo objeto [elementos.Length + Increment]; System.arraycopy (Elements, 0, NewArray, 0, tamanho); } public static void main (string [] args) {myStack Stack = new MyStack (100); for (int i = 0; i <100; i ++) pilha.push (novo número inteiro (i)); for (int i = 0; i <100; i ++) {System.out.println (Stack.pop (). ToString ()); }}}Este programa está disponível e suporta operações de entrada de pilha e pilha comuns. No entanto, há um problema que não foi bem tratado, ou seja, quando a operação da pilha é liberada, a referência ao elemento de pilha na matriz não é liberada, o que faz com que o programa mantenha uma referência a esse objeto (esse objeto é referenciado pela matriz). A GC sempre acredita que esse objeto é acessível, o que significa que não há necessidade de falar sobre a liberação de sua memória. Este é um caso típico de vazamentos de memória. Para isso, o código modificado é:
// pilha public object pop () {if (size == 0) lança new emptyStackStackException (); Objeto o = elementos [-tamanho]; elementos [tamanho] = nulo; retornar o; }O artigo acima tem uma compreensão profunda do mecanismo de coleta de lixo Java e vazamentos de memória. Este é todo o conteúdo que compartilhei com você. Espero que possa lhe dar uma referência e espero que você possa apoiar mais o wulin.com.