Prefacio
Vi una pregunta en SegmentFault: Java tiene un mecanismo GC completo, por lo que habrá un problema de fuga de memoria en Java, y puedo dar un caso de fuga de memoria. Esta visión de la pregunta da la respuesta completa a esta pregunta.
Introducción al mecanismo de reciclaje de basura
Durante el programa en ejecución, se crea cada objeto, se asigna una cierta cantidad de memoria para almacenar datos de objetos. Si sigue asignando memoria, el programa enfrentará el problema de la memoria insuficiente tarde o temprano. Entonces, en cualquier idioma, habrá un mecanismo de recuperación de memoria para liberar la memoria de los objetos caducados para garantizar que la memoria pueda reutilizarse.
El mecanismo de reciclaje de memoria se puede dividir en dos tipos de acuerdo con los roles de implementación. Una es que los programadores se dan cuenta manualmente de la liberación de memoria (como el lenguaje C) y el otro es el mecanismo de reciclaje de memoria incorporado del lenguaje, como el mecanismo de recolección de basura Java que se introducirá en este artículo.
Mecanismo de recolección de basura de Java
En el entorno de tiempo de ejecución del programa, la máquina virtual Java proporciona un hilo de recolección de basura a nivel de sistema (GC, recolección de carbage), que es responsable de recuperar la memoria ocupada por objetos que han perdido referencias. El requisito previo para comprender GC es comprender algunos conceptos relacionados con la recolección de basura. Estos conceptos se introducen uno por uno a continuación.
El estado del objeto en el área de montón JVM
Las instancias de los objetos Java se almacenan en el área del montón de JVM. Para los hilos de GC, estos objetos tienen tres estados.
1. Estado táctil: hay referencias variables en el programa, por lo que este objeto es un estado táctil.
2. Estado reactivado: cuando no hay variables en el programa se refieren a este objeto, el objeto cambiará de un estado tocable a un estado reactivado. El hilo de CG se preparará para llamar al método finalizar de este objeto en un momento determinado (el método finalizar hereda o reescribe el objeto infantil). El código en el método finalizar puede convertir el objeto en un estado táctil; de lo contrario, el objeto se convertirá en un estado intocable.
3. Estado intocable: el hilo GC puede reciclar la memoria de este objeto solo cuando el objeto está en un estado intocable.
Para liberar correctamente los objetos, GC debe monitorear el estado de ejecución de cada objeto, incluida la aplicación, cita, cita, asignación, etc., GC necesita monitorearlo, por lo que GC sabrá sin importar si un objeto está en algún estado anterior.
Como se mencionó anteriormente, GC Threads ejecutará el método finalizar de los objetos de estado resurrectables en un momento determinado. Entonces, ¿cuándo se ejecutará? Dado que los diferentes implementadores de JVM pueden usar diferentes algoritmos para administrar GC, en cualquier momento, los desarrolladores no pueden predecir el momento de los hilos de GC que realizan diversas operaciones (incluida la detección del estado del objeto, la liberación de la memoria del objeto y los métodos de finalización del objeto llamado). Aunque se puede recordar al hilo GC que realice operaciones de recolección de basura lo antes posible a través de las funciones System.gc () y Runtime.gc (), esto no puede garantizar que el hilo GC realice las operaciones de reciclaje correspondientes de inmediato.
Filtración de memoria
Las filtraciones de memoria son causadas por diseños incorrectos de que el programa no puede liberar la memoria que ya no se usa, lo que resulta en un desperdicio de recursos. GC limpiará automáticamente la memoria ocupada por objetos que han perdido referencias. Sin embargo, si siempre se hace referencia a algunos objetos debido a errores de programación, se producirá una filtración de memoria.
Por ejemplo, el siguiente ejemplo. Se utiliza una matriz para implementar una pila, con dos operaciones: entrada de pila y salida de pila.
import com.sun.javafx.collections.ElementObServablelistDecorator; import com.sun.swing.internal.plaf.metal.resources.metal_sv; import java.beans.exceptionListener; import java.util.emptystackexception;/*** creado por Peng el 14-21. */public class Mystack {private Object [] Elements; privado int increment = 10; Tamaño privado int = 0; public mystack (int size) {Elements = new Object [size]; } // Ponga la pila Public Void Push (objeto o) {capacidad (); elementos [tamaño ++] = o; } // Poner el objeto público de pila pop () {if (size == 0) tirar nueva vacíaStackException (); Elementos de retorno [-tamaño]; } // Aumente la capacidad de la capacidad vacía privada de pila () {if (elements.length! = Size) return; Objeto [] newArray = nuevo objeto [Elements.length + increment]; System.ArrayCopy (Elementos, 0, NewArray, 0, tamaño); } public static void main (string [] args) {mystack stack = new mystack (100); para (int i = 0; i <100; i ++) stack.push (nuevo entero (i)); para (int i = 0; i <100; i ++) {System.out.println (stack.pop (). toString ()); }}}Este programa está disponible y admite operaciones de entrada y entrada de pila comunes. Sin embargo, hay un problema que no se ha manejado bien, es decir, cuando se libera la operación de pila, la referencia al elemento de pila en la matriz no se libera, lo que hace que el programa mantenga una referencia a este objeto (la matriz hace referencia a este objeto). GC siempre cree que este objeto es accesible, lo que significa que no hay necesidad de hablar sobre liberar su memoria. Este es un caso típico de fugas de memoria. Para esto, el código modificado es:
// PISTA Public Object Pop () {if (size == 0) tire nuevo vacíoStaceCexception (); Objeto o = elementos [-tamaño]; elementos [tamaño] = nulo; regreso o; }El artículo anterior tiene una comprensión profunda del mecanismo de recolección de basura de Java y las fugas de memoria. Este es todo el contenido que he compartido contigo. Espero que pueda darle una referencia y espero que pueda apoyar más a Wulin.com.