Serie de revisión de entrevistas de JVM: ¿Cómo determinar la basura durante la recolección de basura de JVM? ¿Sabes qué son las GC Roots?

Resumen de la entrevista de JVM

¿Cómo determinar la basura durante la recolección de basura de JVM? ¿Sabes qué son las GC Roots?

Que es basura

En pocas palabras, el espacio en la memoria que ya no se usa es basura.

Cómo juzgar si un objeto se puede reciclar

Recuento de referencias

En Java, las referencias y los objetos están relacionados. Si desea manipular objetos, debe utilizar referencias.

Por lo tanto, es obvio que una forma sencilla es juzgar si un objeto se puede reciclar mediante el recuento de referencias. En pocas palabras, agregue un contador de referencia al objeto

Siempre que haya un lugar para referenciarlo, el valor del contador aumenta en 1

Siempre que falla una referencia, el valor del contador se reduce en 1

El objeto cuyo valor de contador es cero en cualquier momento ya no se puede utilizar, entonces este objeto es un objeto reciclable.

Entonces, ¿por qué no se usa este método en las máquinas virtuales Java convencionales? La razón principal es que es difícil resolver el problema de las referencias circulares entre objetos.

Este algoritmo existe, pero nadie lo ha usado en la actualidad, y no puede resolver el problema de las referencias circulares, simplemente entiéndalo.

imagen-20200318213301603

Enumere los nodos raíz para el análisis de accesibilidad

Algoritmo de ruta de búsqueda raíz

Para resolver el problema de referencia circular del método de recuento de referencias, Java utiliza el método de análisis de accesibilidad:

imagen-20200319113611244

El llamado GC Roots o el "conjunto de raíces" de Tracing Roots es un conjunto de referencias que deben estar activas

La idea básica es usar una serie de objetos llamados GC Roots como punto de partida, comenzando desde este objeto llamado GC Roots y buscando hacia abajo. Si un objeto no está conectado a GC Roots por ninguna cadena de referencia, significa que este objeto es no disponible. Es decir, dado un conjunto de referencias como raíz, atraviesa el gráfico de objetos a través de la relación de referencia, los objetos que se pueden atravesar (alcanzables) se consideran vivos y los objetos que no se atraviesan se consideran muertos.

imagen-20200319114526625

Debe comenzar con el objeto GC Roots, que es similar a Linux / que es el directorio raíz

La parte azul comienza en GC Roots, que se puede acceder cíclicamente

La parte blanca, comenzando por GC Roots, no se puede alcanzar.

Entiende GC Roots en una oración

Supongamos que ahora tenemos tres entidades, a saber, humano, perro y suéter.

Entonces la relación entre ellos es: la gente lleva al perro y el perro usa un suéter, están fuertemente conectados.

Un día la gente desapareció, dejando solo perros y suéteres. En este momento, piense en las personas como GC Roots, porque la conexión de cuerda entre las personas y los perros se pierde.

Luego, el perro puede ser reciclado, es decir, atrapado por la policía y enviado a un albergue para perros callejeros.

Suponiendo una fuerte conexión entre un perro y una persona, el perro no se considerará un perro callejero.

Esos objetos se pueden utilizar como GC Roots

  • Objetos de referencia en la pila de la máquina virtual (área de variable local en el marco de la pila, también llamada tabla de variable local)
  • Objetos referenciados por propiedades estáticas de la clase en el área de métodos
  • Objetos referenciados por constantes en el área de método
  • Objeto de referencia de JNI (método nativo) en la pila de métodos nativos

Descripción del código


/**
 * 在Java中,可以作为GC Roots的对象有:
 * - 虚拟机栈(栈帧中的局部变量区,也叫做局部变量表)中的引用对象
 * - 方法区中的类静态属性引用的对象
 * - 方法区中常量引用的对象
 * - 本地方法栈中的JNI(Native方法)的引用对象
 */
public class GCRootDemo {
    
    


    // 方法区中的类静态属性引用的对象
    // private static GCRootDemo2 t2;

    // 方法区中的常量引用,GC Roots 也会以这个为起点,进行遍历
    // private static final GCRootDemo3 t3 = new GCRootDemo3(8);

    public static void m1() {
    
    
        // 第一种,虚拟机栈中的引用对象
        GCRootDemo t1 = new GCRootDemo();
        System.gc();
        System.out.println("第一次GC完成");
    }
    public static void main(String[] args) {
    
    
        m1();
    }
}

Supongo que te gusta

Origin blog.csdn.net/weixin_43314519/article/details/110309027
Recomendado
Clasificación