traducir significa qué palabras orden inglés ingles español escribe cómo como buscar alfabetico garbage-collection

garbage collection - significa - ¿Cómo implementar un recolector de basura?



traducir al español (8)

¿Alguien podría indicarme una buena fuente sobre cómo implementar la recolección de basura? Estoy haciendo un lenguaje interpretado como ceceo. Actualmente utiliza el recuento de referencias, pero, por supuesto, no puede liberar objetos dependientes de forma circular.

He estado leyendo sobre marcas y barridos, marcado tricolor, moviéndose y moviéndose, incremental y stop-the-world, pero ... No sé cuál es la mejor manera de mantener los objetos cuidadosamente separados en conjuntos mientras se mantiene sobrecarga de memoria de objetos como mínimo, o cómo hacer cosas de forma incremental.

He leído algunos idiomas con recuento de referencias, uso la detección de referencia circular, que podría usar. Soy consciente de que podría usar coleccionistas de libre acceso como Boehm, pero me gustaría aprender a hacerlo yo mismo.

Apreciaría cualquier material en línea con algún tipo de tutorial o ayuda para personas sin experiencia en el tema como yo.


¿Alguien podría indicarme una buena fuente sobre cómo implementar la recolección de basura?

Hay mucho material avanzado sobre recolección de basura. El Manual de recolección de basura es excelente. Pero descubrí que había muy poca información introductoria básica, así que escribí algunos artículos al respecto. Hacer un prototipo de un recolector de basura con barrido de marca describe un GC mínimo de marcaje escrito en F #. El recopilador de basura muy concurrente describe un recopilador simultáneo más avanzado. HLVM es una máquina virtual que escribí que incluye un coleccionista stop-the-world que maneja el enhebrado.

La forma más sencilla de implementar un recolector de basura es:

  1. Asegúrate de que puedes cotejar las raíces globales. Estas son las variables locales y globales que contienen referencias en el montón. Para las variables locales, empújelos a una pila de sombras durante la duración de su alcance.

  2. Asegúrese de poder recorrer el montón, por ejemplo, cada valor en el montón es un objeto que implementa un método de Visit que devuelve todas las referencias de ese objeto.

  3. Mantenga el conjunto de todos los valores asignados.

  4. Asigne llamando a malloc e insertando el puntero en el conjunto de todos los valores asignados.

  5. Cuando el tamaño total de todos los valores asignados excede una cuota, inicie la marca y luego barra las fases. Esto atraviesa recursivamente el montón que acumula el conjunto de todos los valores alcanzables.

  6. La diferencia establecida de los valores asignados menos los valores alcanzables es el conjunto de valores inalcanzables. Itere sobre ellos llamando free y eliminándolos del conjunto de valores asignados.

  7. Establezca la cuota en dos veces el tamaño total de todos los valores asignados.


Como lo sugirió delnan, comencé con un algoritmo de barrido y marcado de tres colores para dejar de pensar en el mundo. Me las arreglé para mantener los objetos en los conjuntos haciéndolos nodos de lista vinculada, pero agrega muchos datos a cada objeto (el puntero virtual, dos punteros a nodos, una enumeración para mantener el color). Funciona perfectamente, no se pierde memoria en valgrind :) De aquí podría intentar agregar una lista gratuita para reciclar, o algún tipo de cosa que detecte cuándo es conveniente detener el mundo, o un enfoque incremental, o un asignador especial para evitar la fragmentación u otra cosa. Si puede indicarme dónde encontrar información o consejo (no sé si puede comentar una pregunta respondida) sobre cómo hacer estas cosas o qué hacer, estaría muy agradecido. Revisaré el GC de Lua mientras tanto.


Estoy haciendo un trabajo similar para mi intérprete postdata. más información a través de mi pregunta. Estoy de acuerdo con el comentario de Delnan de que un simple algoritmo de marcaje es un buen lugar para comenzar. Necesitará funciones para establecer marca, marca de verificación, marca clara e iteradores para todos sus contenedores. Una optimización fácil es marcar con claridad cada vez que se asigna un nuevo objeto, y borrar la marca durante el barrido; de lo contrario, necesitará un pase completo para borrar las marcas antes de comenzar a configurarlas.


Implementé un recolector de basura copiado al estilo Cheney en C en aproximadamente 400 SLOC. Lo hice por un lenguaje de tipo estático y, para mi sorpresa, la parte más difícil fue en realidad comunicar la información de qué cosas son punteros y cuáles no. En un lenguaje de tipado dinámico, esto es probablemente más fácil ya que debe usar alguna forma de esquema de etiquetado.

También hay una nueva versión del libro estándar sobre recolección de basura que sale: "The Garbage Collection Handbook: The Art of Automatic Memory Management" de Jones, Hosking, Moss . (El sitio de Amazon UK dice el 19 de agosto de 2011)





Una cosa que aún no he mencionado es el uso de los controles de memoria. Se puede evitar la necesidad de duplicar la memoria (como sería necesario con el algoritmo de copia al estilo de Cheney) si cada referencia de objeto es un puntero a una estructura que contiene la dirección real del objeto en cuestión. El uso de identificadores para objetos de memoria hará que ciertas rutinas sean un poco más lentas (uno debe volver a leer la dirección de memoria de un objeto cada vez que haya sucedido algo que lo mueva) pero para sistemas de subproceso único donde la recolección de basura solo ocurrirá en tiempos predecibles, no es demasiado problema y no requiere soporte especial del compilador (los sistemas multi-threaded GC probablemente requerirán metadatos generados por el compilador ya sea que usen manejadores o punteros directos).

Si uno utiliza identificadores y utiliza una lista vinculada para identificadores activos (el mismo almacenamiento puede usarse para contener una lista vinculada para identificadores muertos que necesitan reasignación), uno puede, después de marcar el registro maestro para cada identificador, avanzar a través de la lista de identificadores , en orden de asignación y copie el bloque al que hace referencia ese identificador al comienzo del montón. Como los identificadores se copiarán en orden, no será necesario utilizar un segundo área de almacenamiento dinámico. Además, las generaciones pueden ser respaldadas haciendo un seguimiento de algunos punteros de top-of-heap. Cuando compacte la memoria, comience simplemente compactando los elementos agregados desde el último GC. Si eso no libera suficiente espacio, compacte los elementos agregados desde el último nivel 1 GC. Si eso no libera suficiente espacio, compacte todo. La fase de marcado probablemente tendría que actuar sobre objetos de todas las generaciones, pero la costosa etapa de compactación no lo haría.

En realidad, usando un enfoque basado en el manejo, si se marcan cosas de todas las generaciones, se podría, si se desea, calcular en cada GC la cantidad de espacio que podría liberarse en cada generación. Si la mitad de los objetos en Gen2 están muertos, puede valer la pena hacer una colección Gen2 para reducir la frecuencia de las colecciones Gen1.