2009-04-21 19 views
21

En una terminología de hombre común, ¿cómo funciona el mecanismo de recolección de basura?¿Cómo funciona el mecanismo de recolección de basura?

¿Cómo se identifica que un objeto está disponible para la recolección de basura?

Además, ¿qué significa Reference Counting, Mark and Sweep, Copying, Train en los algoritmos de GC?

+4

Nopes ... no lo es. Probablemente parece solo porque lo puse de esa manera. De cualquier manera –

+1

Yo recomendaría leer el bastante bueno, documento ilustrado de 34 páginas, [* Uniprocessor Garbage Collection Techniques *, por Paul R. Wilson (1992)] (http://www.cse.nd.edu/~dthain /courses/cse40243/spring2006/gc-survey.pdf), que explica los conceptos detrás de las técnicas básicas de recolección de basura (recuento de referencias, marcado y barrido, marca compacta, incremental, generacional). – stakx

Respuesta

29

Cuando utiliza un lenguaje con recolección de basura no obtendrá acceso a la memoria directamente. Más bien, se te da acceso a cierta abstracción sobre esos datos. Una de las cosas que se abstrae correctamente es la ubicación real en la memoria del bloque de datos, así como punteros a otros bloques de datos. Cuando se ejecuta el recolector de elementos no utilizados (esto ocurre de vez en cuando), comprobará si aún tiene una referencia a cada uno de los bloques de memoria que le ha asignado. Si no lo hace, liberará esa memoria.

La principal diferencia entre los diferentes tipos de recolectores de basura es su eficiencia, así como cualquier limitación sobre qué tipo de esquemas de asignación pueden manejar.

El más simple es el recuento de referencias adecuado. Cada vez que crea una referencia a un objeto, se incrementa un contador interno en ese objeto, cuando hace la referencia o deja de estar en el alcance, el contador en el (anterior) objeto objetivo se reduce. Cuando este contador llega a cero, el objeto ya no se remite y puede liberarse.

El problema con el recuento de basureros de recuento de referencias es que no pueden tratar con datos circulares. Si el objeto A tiene una referencia al objeto B y que a su vez tiene alguna referencia (directa o indirecta) al objeto A, nunca podrán liberarse, incluso si ninguno de los objetos de la cadena está arbitrado fuera de la cadena (y por lo tanto no lo son). t accesible para el programa en absoluto).

El algoritmo de marca y barrido, por otro lado puede manejar esto. El algoritmo de marca y barrido funciona al detener periódicamente la ejecución del programa, marcar cada elemento que el programa ha asignado como inalcanzable. El programa luego ejecuta todas las variables que tiene el programa y marca lo que señalan como alcanzable. Si cualquiera de estas asignaciones contiene referencias a otros datos en el programa, esos datos también se marcan como alcanzables, etc.

Esta es la parte de marca del algoritmo. En este punto , todo el programa al que se puede acceder, sin importar cuán indirectamente, se marque como accesible y todo lo que el programa no puede alcanzar se marca como inalcanzable. El recolector de basura ahora puede reclamar de forma segura la memoria asociada con los objetos marcados como inalcanzables.

El problema con el algoritmo de marcaje y barrido es que no es tan eficiente: todo el programa tiene que detenerse para ejecutarlo, y muchas de las referencias de objeto no van a cambiar.

Para mejorar esto, el algoritmo de marca y barrido se puede ampliar con la llamada "recolección de basura generacional". En este modo, los objetos que han estado en el sistema para cierto número de colecciones de basura se promueven a la generación anterior, que no se comprueba con tanta frecuencia.

Esto mejora la eficiencia porque los objetos tienden a morir jóvenes (piense en una cuerda cambiada dentro de un bucle, dando como resultado quizás una vida de unos cientos de ciclos) o viva mucho tiempo (los objetos utilizados para representar la ventana principal de un aplicación, o la conexión de base de datos de un servlet).

Se puede encontrar mucha más información detallada en wikipedia.

añadido basado en los comentarios:

Con la marca y barrer algoritmo (así como cualquier otro algoritmo de recolección de basura, excepto el recuento de referencias) la recolección de basura hacer no ejecutan en el contexto de su programa, ya tiene que poder acceder a cosas a las que su programa no puede acceder directamente. Por lo tanto, no es correcto decir que el recolector de basura se ejecuta en la pila.

+3

Claro, fácil y breve. Una pregunta aquí mencionó acerca de marcar y barrer que verifica todas las variables en su programa. Si no estoy equivocado, las referencias existen en la pila y el objeto en el montón, entonces, ¿cómo podemos asociar ese proceso de GC que se ejecuta en Heap? –

3

La recolección de basura es simplemente saber si hay alguna necesidad futura de variables en su programa, y ​​si no, recopilarlas y eliminarlas.

El énfasis está en la palabra basura, algo que es completamente utilizado en su casa se tira a la basura y el hombre de la basura lo hace por ti al venir a recogerlo y se lo quite para darle más espacio en tu basura de la casa.

Saldo de referencias, Mark y barrido, copia, etc. tren se discuten en detalle en buena conteo GC FAQ

4
  • Referencia - Cada objeto tiene un recuento que se incrementa cuando alguien toma una referencia a la objeto, y disminuido cuando alguien libera la referencia. Cuando el recuento de referencias va a cero, el objeto se elimina. COM usa este enfoque.
  • Marcar y arrastrar - Cada objeto tiene una bandera si está en uso. Comenzando en la raíz del gráfico del objeto (variables globales, locals en pilas, etc.) cada objeto referenciado obtiene su bandera establecida, y así sucesivamente en la cadena. Al final, se eliminan todos los objetos que no están referenciados en el gráfico.

El recolector de basura para el CLR se describe en este slidedeck. "Roots" en la diapositiva 15 son las fuentes de los objetos que entran primero en el gráfico. Sus campos de miembros, etc., se usan para buscar otros objetos en el gráfico.

Wikipedia describe varios de estos enfoques con mucho más y mejor detalle.

+0

He revisado la wikipedia ... en realidad, lo que me molesta es Object Graph, cómo se mantiene y atraviesa una rutina de GC. –

+0

Actualicé mi respuesta con una vista de 10k para compilar el gráfico de objetos. – Michael

0

La manera general en que se hace es que el número de referencias a un objeto se mantiene en segundo plano, y cuando ese número es cero, el objeto está SUJETO a recolección de basura, sin embargo, el GC no se activará hasta que sea explícitamente necesario porque es una operación costosa. Lo que sucede cuando comienza es que el GC pasa por el área de memoria administrada y encuentra todos los objetos que no tienen referencias. El gc borra esos objetos llamando primero a sus destructores, permitiéndoles limpiarlos y luego libera la memoria. Comúnmente, el GC compactará el área de memoria administrada moviendo todos los objetos supervivientes a un área de la memoria, permitiendo que se realicen más asignaciones.

Como dije, este es un método que conozco, y se está realizando una gran cantidad de investigación en esta área.

0

Garbage collection es un gran tema, y ​​hay muchas formas de implementarlo.

Pero, en pocas palabras, el recolector de basura mantiene un registro de todas las referencias a cualquier cosa creada a través del operador new, incluso si el uso del operador estaba oculto (por ejemplo, en un método Type.Create()). Cada vez que agrega una nueva referencia al objeto, se determina raíz de esa referencia y se agrega a la lista, si es necesario. Se elimina una referencia cada vez que sale del alcance.

Cuando no hay más referencias a un objeto, puede (no "será") recolectarse. Para mejorar el rendimiento y garantizar que la limpieza necesaria se realice correctamente, las colecciones se agrupan para varios objetos a la vez y se producen a lo largo de varias generaciones.

Cuestiones relacionadas