Pregunta

¿Cuáles son las raíces en la recolección de basura?

He leído la definición de raíz como "cualquier referencia a la que el programa pueda acceder" y la definición de Live es que un objeto que se está utilizando, que puede ser una variable local, variable estática.

Estoy poco confundido con discriminar la diferencia entre raíz y objetos vivos.

¿Qué es el camino a la raíz? ¿Cómo funcionan los objetos root y vivos?

¿Alguien puede elaborar?

¿Fue útil?

Solución

Si piensa en los objetos en la memoria como un árbol, las "raíces" serían los nodos raíz, cada objeto de inmediato accesible por su programa.

Person p = new Person();
p.car = new Car(RED);
p.car.engine = new Engine();
p.car.horn = new AnnoyingHorn();

Hay cuatro objetos; Una persona, un auto rojo, su motor y bocina. Dibuja el gráfico de referencia:

     Person [p]
        |
     Car (red)
   /           \
Engine    AnnoyingHorn

Y terminarás con Person en la "raíz" del árbol. Está en vivo porque está a la referencia por una variable local, p, que el programa podría usar en cualquier momento para consultar el Person objeto. Esto también va por los otros objetos, a través de p.car, p.car.engine, etc.

Ya que Person Y todos los demás objetos conectados recursivamente están en vivo, habría problemas si el GC los recopilara.

Considere, sin embargo, si lo siguiente se ejecuta después de un tiempo:

p.car = new Car(BLUE);

Y vuelve a dibujar el gráfico:

     Person [p]
        |
     Car (blue)       Car (red)
                    /           \
                Engine    AnnoyingHorn

Ahora el Person es accesible a través de p y el coche azul a través p.car, pero no hay forma de que el automóvil rojo o sus piezas se puedan acceder nuevamente: no están conectados a una raíz viva. Se pueden recolectar con seguridad.

Por lo tanto, es realmente una cuestión de tomar cada punto de partida (cada variable local, globales, estadísticas, todo en otros hilos y marcos de pila), cada raíz, y siguiendo de manera recursiva todas las referencias para formar una lista de todos los objetos "en vivo": objetos que están en uso e inadecuados para la eliminación. Todo lo demás es basura, esperando ser recolectado.

Otros consejos

Las raíces GC (recolector de basura) son objetos especiales para el recolector de basura. El recolector de basura recolecta aquellos objetos que no son raíces GC y no son accesibles por referencias de Roots GC.

Hay varios tipos de raíces GC. Un objeto puede pertenecer a más de un tipo de raíz. Los tipos de raíz son:

  • Clase - Clase cargada por System Class Loader. Tales clases nunca se pueden descargar. Pueden mantener objetos a través de campos estáticos. Tenga en cuenta que las clases cargadas por cargadores de clase personalizados no son raíces, a menos que las instancias correspondientes de java.lang.class sean raíces de otro tipo (s).
  • Tema - Hilo en vivo
  • PISTA LOCAL - Variable local o parámetro del método Java
  • JNI Local - Variable local o parámetro del método JNI
  • JNI Global - Referencia Global JNI
  • Monitor utilizado: objetos utilizados como monitor para la sincronización
  • Sostenido por JVM - Objetos retenidos por la recolección de basura por JVM para sus propósitos. En realidad, la lista de tales objetos depende de la implementación de JVM. Los posibles casos conocidos son: el cargador de clases del sistema, algunas clases de excepción importantes que el JVM conoce, algunos objetos preactivados para el manejo de excepciones y cargadores de clase personalizados cuando están en proceso de carga de clases. Desafortunadamente, JVM no proporciona absolutamente ningún detalle adicional para tales objetos. Por lo tanto, depende del analista decidir en qué caso pertenece un cierto "en poder de JVM".

(crédito a Sitio web de YourKit)

No mencionado por su Kit es el hecho de que los objetos que esperan finalización se conservarán como raíces hasta que el GC ejecute el finalize() método. Eso puede causar retención transitoria de gráficos grandes de manera inesperada. La regla general no es usar finalizadores (pero esa es una pregunta diferente).

Raíces o recolección de basura Las raíces son los objetos que son siempre accesible. Si un objeto siempre es accesible, entonces no es elegible para la recolección de basura; Por lo tanto, las raíces siempre son inelegibles para la recolección. Es el conjunto inicial de objetos desde donde se determinan la accesibilidad de todos los demás objetos en el montón.

Otros objetos en el montón accesible de las raíces de recolección de basura se consideran que son objetos vivos, e ineligible para la recolección; Los objetos que son inalcanzables pueden marcarse para la recuperación.

Conozco a Java más que la plataforma .NET, así que hablaré solo por uno. En la plataforma Java, las raíces GC en realidad dependen de la implementación. Sin embargo, en la mayoría de los tiempos de ejecución, las raíces GC tienden a ser los operandos en la pila (ya que actualmente están en uso por hilos) y miembros de clases de clase (estática). La accesibilidad se calcula a partir de estos objetos en la mayoría de las JVM. Hay otros casos en los que los parámetros y operandos locales utilizados por las llamadas JNI se considerarán parte del conjunto de raíces, y también se utilizan para calcular la accesibilidad.

Espero que esto aclare cualquier duda persistente sobre lo que es una raíz (conjunto) y qué es un objeto vivo.

los Sitio web de IBM Enumera lo siguiente como Roots GC.

Tenga en cuenta que algunos de estos son construcciones artificiales realizadas por un analizador de memoria, pero aún es importante tener en cuenta si está mirando un vertedero de montón.

  • Clase del sistema

    Una clase cargada por el cargador de bootstrap o el cargador de clase del sistema. Por ejemplo, esta categoría incluye todas las clases en el archivo rt.jar (parte del entorno de tiempo de ejecución Java), como las del paquete Java.util.*.

  • JNI local

    Una variable local en el código nativo, por ejemplo, el código JNI definido por el usuario o el código interno JVM.

  • JNI Global

    Una variable global en el código nativo, por ejemplo, el código JNI definido por el usuario o el código interno JVM.

  • Bloque de hilo

    Un objeto al que se hizo referencia desde un bloque de hilo activo.

  • Hilo

    Un hilo en ejecución.

  • Monitor ocupado

    Todo lo que llamó los métodos Wait () o notificar (), o que se sincroniza, por ejemplo llamando al método sincronizado (objeto) o ingresando un método sincronizado. Si el método era estático, la raíz es una clase, de lo contrario es un objeto.

  • Java local

    Una variable local. Por ejemplo, los parámetros de entrada o objetos de métodos creados localmente que todavía están en la pila de un hilo. Pila nativa

    Parámetros de entrada o salida en código nativo, por ejemplo, código JNI definido por el usuario o código interno JVM. Muchos métodos tienen partes nativas, y los objetos que se manejan como parámetros del método se convierten en raíces de recolección de basura. Por ejemplo, los parámetros utilizados para operaciones de archivo, red, E/S o reflexión.

  • Finalizador

    Un objeto que está en una cola, esperando que se ejecute un finalizador.

  • No minucioso

    Un objeto que tiene un método final, pero no fue finalizado, y aún no está en la cola de finalizador.

  • Inalcanzable

    Un objeto inalcanzable de cualquier otra raíz, pero fue marcado como una raíz por el analizador de memoria para que el objeto pueda incluirse en un análisis.

    Los objetos inalcanzables son a menudo el resultado de optimizaciones en el algoritmo de recolección de basura. Por ejemplo, un objeto podría ser un candidato para la recolección de basura, pero ser tan pequeño que el proceso de recolección de basura sería demasiado costoso. En este caso, el objeto podría no ser recolectado basura y podría permanecer como un objeto inalcanzable.

    Por defecto, los objetos inalcanzables se excluyen cuando el analizador de memoria analiza el volcado de montón. Por lo tanto, estos objetos no se muestran en el histograma, el árbol dominador o los resultados de la consulta. Puede cambiar este comportamiento haciendo clic en Archivo> Preferencias ...> Herramientas de diagnóstico de IBM para Java - Analizador de memoria, luego seleccionando la casilla de verificación Garantía de objetos inalámbricos.

  • Marco de la pila Java

    Un marco de pila Java, que contiene variables locales. Este tipo de raíz de recolección de basura solo se genera si establece las preferencias para tratar los marcos de la pila Java como objetos. Para obtener más información, consulte los conceptos básicos de Java: hilos y consultas de pila de hilos.

  • Desconocido

    Un objeto de tipo de raíz desconocido. Algunos volcados, como los archivos de IBM Portable Heap (.phd), no tienen información raíz. En este caso, el analizador analizador de memoria marca objetos que no tienen referencias entrantes, o son inalcanzables de ninguna otra raíz, como se desconoce. Esta acción asegura que el analizador de memoria retenga todos los objetos en el volcado.

En Java diría que los hilos son los objetos raíz. Cada objeto vivo se puede volver a rastrearse hasta un hilo vivo. Por ejemplo, una clase hace referencia a un objeto estático, a la que se hace referencia un cargador de clase, a la que se hace referencia otra clase, a la que se hace referencia una instancia de esa clase, ... a la que se hace referencia un ejecutable, a la que se hace referencia por un hilo en vivo. (Tenga en cuenta que las clases pueden ser gc'ed, no pueden ser raíces)

También podemos considerar una raíz "real" para todos los hilos, sin embargo, eso está fuera del ámbito de Java estándar. No podemos decir qué es y cómo hace referencia a todos los hilos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top