X-Git-Url: https://git.llucax.com/z.facultad/75.00/informe.git/blobdiff_plain/3bcfc587ccfd82d22300848f7e6530f79e2f80b5..8880544d4749ac2769338ccc8eedfbdaca4e7b75:/source/gc.rst diff --git a/source/gc.rst b/source/gc.rst index 0699b3a..0b91155 100644 --- a/source/gc.rst +++ b/source/gc.rst @@ -1681,7 +1681,7 @@ linealmente. -.. _ref_gc_copy_2space: +.. _ref_gc_copy: Copia de semi-espacio ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1689,12 +1689,11 @@ Copia de semi-espacio Este algoritmo consiste en hacer una partición del *heap* en 2 mitades o *semi-espacios*, llamados usualmente *Fromspace* y *Tospace*. El primero se utiliza para alocar nuevas celdas de forma lineal, asumiendo un *heap* -contiguo, incrementando un puntero (ver figura :vref:`fig:gc-copy-2space`). -Esto se conoce como *pointer bump allocation* y es, probablemente, la forma -más eficiente de alocar memoria (tan eficiente como alocar memoria en el -*stack*). +contiguo, incrementando un puntero (ver figura :vref:`fig:gc-copy`). Esto se +conoce como *pointer bump allocation* y es, probablemente, la forma más +eficiente de alocar memoria (tan eficiente como alocar memoria en el *stack*). -.. fig:: fig:gc-copy-2space +.. fig:: fig:gc-copy Estructura del *heap* de un recolector con copia de semi-espacios. @@ -1722,21 +1721,22 @@ más eficiente de alocar memoria (tan eficiente como alocar memoria en el /| /| BB "Tospace" -La segunda mitad (*Tospace*) permanece ociosa hasta que se agota el espacio en -el *Fromspace*; en ese momento comienza el proceso de recolección de basura -que consiste en recorrer el grafo de conectividad, copiando las celdas *vivas* -del *Fromspace* al *Tospace* de manera contigua, como si estuvieran alocando -por primera vez. Como la posición en memoria de las celdas cambia al ser -movidas, es necesario actualizar la dirección de memoria de todas las celdas -*vivas*. Para esto se almacena una dirección de memoria de redirección, -*forwarding address*, en las celdas que mueven. La *forwarding address* sirve -a su vez de marca, para no recorrer una celda dos veces (como se explica en -:ref:`ref_gc_intro_mark`). Cuando se encuentra una celda que ya fue movida, -simplemente se actualiza la referencia por la cual se llegó a esa celda para -que apunte a la nueva dirección, almacenada en la *forwarding address*. Una -vez finalizado este proceso, el *Fromspace* y *Tospace* invierten roles y se -prosigue de la misma manera (todo lo que quedó en el viejo *Fromspace* es -*basura* por definición, por lo que se convierte el *Tospace*). +La segunda mitad (*Tospace*) permanece inutilizada hasta que se agota el +espacio en el *Fromspace*; en ese momento comienza el proceso de recolección +de basura que consiste en recorrer el grafo de conectividad, copiando las +celdas *vivas* del *Fromspace* al *Tospace* de manera contigua, como si +estuvieran alocando por primera vez. Como la posición en memoria de las celdas +cambia al ser movidas, es necesario actualizar la dirección de memoria de +todas las celdas *vivas*. Para esto se almacena una dirección de memoria de +redirección, *forwarding address*, en las celdas que mueven. La *forwarding +address* sirve a su vez de marca, para no recorrer una celda dos veces (como +se explica en :ref:`ref_gc_intro_mark`). Cuando se encuentra una celda que ya +fue movida, simplemente se actualiza la referencia por la cual se llegó a esa +celda para que apunte a la nueva dirección, almacenada en la *forwarding +address*. Una vez finalizado este proceso, el *Fromspace* y *Tospace* +invierten roles y se prosigue de la misma manera (todo lo que quedó en el +viejo *Fromspace* es *basura* por definición, por lo que se convierte el +*Tospace*). A continuación se presenta una implementación sencilla de los servicios provistos por este tipo de recolectores. Cabe destacar que este tipo de