From: Leandro Lucarella Date: Tue, 16 Jun 2009 00:35:16 +0000 (-0300) Subject: Terminar capítulo Recolección de basura en D X-Git-Tag: entrega-2010-10-08~43 X-Git-Url: https://git.llucax.com/z.facultad/75.00/informe.git/commitdiff_plain/12b4722b4c418b9d60d75c0acdd9e5cac133af6a?ds=inline Terminar capítulo Recolección de basura en D Completar la introducción del capítulo y la sección de Características y necesidades particulares de D. --- diff --git a/source/dgc.rst b/source/dgc.rst index a0b9ce5..44b31d0 100644 --- a/source/dgc.rst +++ b/source/dgc.rst @@ -4,7 +4,7 @@ de recolección de basura en dicho lenguaje (se explica por qué las particularidades descriptas en la sección anterior complican la recolección de basura y cuales son las que más molestan). - ESTADO: SIN EMPEZAR, REVISAR LO HECHO + ESTADO: TERMINADO .. _dgc: @@ -12,14 +12,160 @@ Recolección de basura en D ============================================================================ -TODO +D_ propone un nuevo desafío en cuanto al diseño de un recolector de basura, +debido a la gran cantidad características que tiene y paradigmas que soporta. +D_ ya cuenta con un recolector que hace lo necesario para funcionar de forma +aceptable, pero su diseño e implementación son relativamente sencillas +comparadas con el :ref:`estado del arte ` de la recolección de basura +en general. Además la implementación actual presenta una serie de problemas +que se evidencia en las quejas que regularmente la comunidad de usuarios de D_ +menciona en el grupo de noticias. +En esta sección se analizarán las necesidades particulares de D_ con respecto +a la recolección de basura. También se analiza el diseño e implementación del +recolector actual y finalmente se presenta una recompilación de los +principales problemas que presenta. -Dificultades para recolectar basura en D + + +.. _dgc_needs: + +Características y necesidades particulares de D_ ---------------------------------------------------------------------------- -TODO +En esta sección se hará un recorrido por las características y necesidades +particulares que tiene D_ como lenguaje con respecto a la recolección de +basura. + + + +.. _dgc_prob_low_level: + +Programación de bajo nivel (*system programming*) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Sin dudas las características de D_ que lo hacen más complejo a la hora de +implementar un recolector de basura son sus capacidades de programación de +bajo nivel (ver :ref:`d_low_level`). + +Al proveer acceso a *aasembly*, permitir estructuras de tipo *union* y ser +compatible con C/C++, el recolector de basura tiene muchas restricciones. Por +ejemplo debe tratar de forma conservativa los registros y el *stack*, ya que +es la única forma de interactuar de forma segura con C/C++ y *assembly*. + +Además debe poder interactuar con manejo de memoria explícito, ya sea +omitiendo por completo el *heap* del recolector o liberando explícitamente +memoria de éste. Esta característica es muy inusual en un recolector, +a excepción de recolectores conservativos diseñados para C/C++ que tienen las +mismas (o más) limitaciones. + +El control sobre la alineación de memoria es otra complicación sobre el +recolector de basura, incluso aunque éste sea conservativo. Dado que tratar la +memoria de forma conservativa byte a byte sería impracticable (tanto por la +cantidad de falsos positivos que esto provocaría como por el impacto en la +eficiencia por el exceso de posibles punteros a revisar, además de lo +ineficiente que es operar sobre memoria no alineada), en general el recolector +asume que el usuario nunca va a tener la única referencia a un objeto en una +estructura no alineada al tamaño de palabra. + + + +.. _d_prob_high_level: + +Programación de alto nivel +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Las características de programación de alto nivel también impone dificultades +o restricciones al recolector de basura (ver :ref:`d_high_level`). Por ejemplo +el soporte de rebanado (*slicing*) de arreglos hace que el recolector deba +soportar punteros *interiores* [#dgcinterior]_ (esto también es necesario +porque en general en D_ o en cualquier lenguaje de bajo nivel se puede tener +un puntero a cualquier parte de una celda). + +.. [#dgcinterior] Los punteros *interiores* son aquellos que en vez de apuntar + al inicio de una celda, apuntan a una dirección arbitraria dentro de ella. + Esto no es posible en muchos lenguajes de programación, como por ejemplo + Java_, lo que simplifica la recolección de basura. + +Los arreglos dinámicos y asociativos en particular dependen fuertemente del +recolector de basura, en particular cuando se agregan elementos (o se +concatenan dos arreglos). + +Dado que los *strings* son arreglos dinámicos y que el lenguaje provee un buen +soporte de arreglos dinámicos y asociativos y *slicing*, es de esperarse que +el recolector deba comportarse de forma correcta y eficiente ante las +operaciones más típicas de estas estructuras que dependan de él. + + + +.. _dgc_prob_types: + +Información de tipos +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Hasta aquí D_ comparte todas las restricciones con respecto a la recolección +de basura con los lenguajes de bajo nivel que no tienen ningún soporte para +recolectar basura. Sin embargo, a diferencia de éstos, D_ tiene una +información de tipos más rica. Al momento de asignar memoria D_ puede proveer +cierta información sobre el objeto a asignar (como si puede contener punteros +o no) que puede ser utilizada por el recolector para realizar una recolección +más precisa (ver :ref:`gc_conserv`). + +En general esta información no es suficiente como para implementar un +recolector completamente preciso (no al menos sin agregar un mejor soporte de +reflexión al lenguaje) pero puede ser de ayuda considerable para el +recolector. + + + +.. _dgc_prob_final: + +Orientación a objetos y finalización +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +D_ soporta el paradigma de orientación a objetos, donde es común permitir que +un objeto, al ser destruido, realice alguna tarea de finalización (a través de +una función miembro llamada *destructor*, o ``~this()`` en D_). Esto significa +que el recolector, al encontrar que un objeto no es más referenciados, debe +ejecutar el destructor. + +La especificación dice: + + The garbage collector is not guaranteed to run the destructor for all + unreferenced objects. Furthermore, the order in which the garbage collector + calls destructors for unreference objects is not specified. This means that + when the garbage collector calls a destructor for an object of a class that + has members that are references to garbage collected objects, those + references may no longer be valid. This means that destructors cannot + reference sub objects. + +Afortunadamente el orden de finalización no está definido, ya que esto sería +extremadamente difícil de proveer por un recolector (si no imposible). Esto +significa que si bien se ejecutan el destructores de los objetos que dejan de +ser alcanzables desde el *root set*, no se define en que orden se hace, y por +lo tanto un objeto no puede acceder a sus atributos que sean referencias +a otros objetos en un destructor. + +Esta restricción en realidad se ve relaja con el soporte de *RAII*. Si se +utiliza la palabra clave ``scope`` al crear una serie de objetos, estos serán +destruídos determinísticamente al finalizar el *scope* actual en el orden +inverso al que fueron creados y, por lo tanto, un usuario podría hacer uso de +los atributos que sean referencias a otros objetos creados con ``scope`` si el +orden en que fueron creados (y por lo tanto en que serán destruidos) se lo +permite. + +Sin embargo no hay forma actualmente de saber dentro de un destructor si este +fue llamado determinísticamente o no, por lo tanto es virtualmente imposible +hacer uso de esta distinción, a menos que una clase sea declarada para ser +creada solamente utilizando la palabra reservada ``scope``. + +Cabe aclarar que estrictamente hablando, según la especificación de D_, el +recolector no debe garantizar la finalización de objetos bajo ninguna +circunstancia, es decir, el recolector podría no llamar a ningún destructor. +Sin embargo esto es probablemente un problema de redacción vaga y dadas las +garantías que provee la implementación actual la comunidad de D_ cuenta con +ellas porque además son deseables (y sencillas de implementar).