]> git.llucax.com Git - z.facultad/75.00/informe.git/commitdiff
Agregar Problemas y limitaciones del recolector actual
authorLeandro Lucarella <llucax@gmail.com>
Mon, 15 Jun 2009 05:56:24 +0000 (02:56 -0300)
committerLeandro Lucarella <llucax@gmail.com>
Tue, 16 Jun 2009 00:40:05 +0000 (21:40 -0300)
source/d.rst
source/dgc.rst
source/referencias.rst

index f3f90dbb85582e00ad6c3d950aed8dae83ee5b51..2105e796a1b3ec0d02db812c5c554b0775b25ed0 100644 (file)
@@ -840,6 +840,8 @@ Propiedades (*properties*):
 
 
 
+.. _d_dbc:
+
 Programación confiable
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
index f3327bdbd11ffab83324e48e17511fa9d622b0fa..a0b9ce525b8b6a8f195f06210e32760ee914d4f3 100644 (file)
@@ -1227,85 +1227,276 @@ asignación de memoria.
 Problemas y limitaciones
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-TODO
-
-
-
-
-Como se ha visto, D_ es un lenguaje de programación muy completo, pero aún
-tiene algunos aspectos inconclusos. Su recolector de basura está en un estado
-de evolución muy temprana. Se trata de un marcado y barrido (*mark and sweep*)
-conservativo que, en ciertas circunstancias, no se comporta como es debido, ya
-que revisa toda la memoria del programa en busca de referencias a objetos en
-el *heap* (en vez de revisar sólo las partes que almacenan punteros). Esto
-produce que, en ciertos casos, por ejemplo al almacenar arreglos de número
-o *strings* en la pila, el recolector de basura se encuentre con *falsos
-positivos*, pensando que un área del *heap* está siendo utilizada cuando en
-realidad el puntero que hacía referencia a ésta no era tal. Este efecto puede
-llevar a la pérdida de memoria masiva, llegando al límite de que eventualmente
-el sistema operativo tenga que matar al programa por falta de memoria
-[DNG46407]_. Aún cuando el programa no tenga estos problemas de por sí, por
-usar datos que no pueden ser confundidos con direcciones de memoria, este
-problema podría ser explotado por ataques de seguridad, inyectando valores que
-sí sean punteros válidos y provocando el efecto antes mencionado que deriva en
-la terminación abrupta del programa [DNG35364]_.  Finalmente, a estos problemas
-se suman los problemas de *performance* [DNG43991]_.
-
-Es difícil que D_ pueda ser un lenguaje de programación exitoso si no provee un
-recolector de basura eficiente y que realmente evite la pérdida masiva de
-memoria. Por otro lado, D_ podría atraer a una base de usuarios mucho más
-amplia, si la gama de estrategias de recolección es más amplia, pudiendo lograr
-adaptarse a más casos de uso sin llegar al límite de tener que caer en el
-manejo explícito de memoria y perder por completo las ventajas de la
-recolección de basura (con la consecuencia ya mencionada de que el manejo de
-memoria tenga que pasar a ser parte de las interfaces y la complejidad que esto
-agrega al diseño -y uso- de una biblioteca).
-
-
+A continuación se presentan los principales problemas encontrados en la
+implementación actual del recolector de basura de D_. Estos problemas surgen
+principalmente de la observación del código y de aproximadamente 3 años de
+participación y observación del grupo de noticias, de donde se obtuvieron los
+principales problemas percibidos por la comunidad que utiliza el lenguaje.
+
+
+Complejidad del código y documentación
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+El análisis del código fue muy complicado debido a la falta de documentación
+y desorganización del código. Además se nota que el recolector ha sido escrito
+en una fase muy temprana y que a ido evolucionando a partir de ello de forma
+desprolija y sin ser rescrito nunca para aprovechar las nuevas características
+que el lenguaje fue incorporando (por ejemplo *templates*).
+
+Estos dos problemas (código complicado y falta de documentación) producen un
+efecto de círculo vicioso, porque provocan que sea complejo entender el
+recolector actual y en consecuencia sea muy complicado escribir documentación
+o mejorarlo. Esto a su vez provoca que, al no disponer de una implementación
+de referencia sencilla, sea muy difícil implementar un recolector nuevo.
+
+Este es, probablemente, la raíz de todos los demás problemas del recolector
+actual. Para ilustrar la dimensión del problema se presenta la implementación
+real de la función ``bigAlloc()``::
+
+    /**
+     * Allocate a chunk of memory that is larger than a page.
+     * Return null if out of memory.
+     */
+    void *bigAlloc(size_t size)
+    {
+        Pool*  pool;
+        size_t npages;
+        size_t n;
+        size_t pn;
+        size_t freedpages;
+        void*  p;
+        int    state;
+
+        npages = (size + PAGESIZE - 1) / PAGESIZE;
+
+        for (state = 0; ; )
+        {
+            // This code could use some refinement when repeatedly
+            // allocating very large arrays.
+
+            for (n = 0; n < npools; n++)
+            {
+                pool = pooltable[n];
+                pn = pool.allocPages(npages);
+                if (pn != OPFAIL)
+                    goto L1;
+            }
+
+            // Failed
+            switch (state)
+            {
+            case 0:
+                if (disabled)
+                {   state = 1;
+                    continue;
+                }
+                // Try collecting
+                freedpages = fullcollectshell();
+                if (freedpages >= npools * ((POOLSIZE / PAGESIZE) / 4))
+                {   state = 1;
+                    continue;
+                }
+                // Release empty pools to prevent bloat
+                minimize();
+                // Allocate new pool
+                pool = newPool(npages);
+                if (!pool)
+                {   state = 2;
+                    continue;
+                }
+                pn = pool.allocPages(npages);
+                assert(pn != OPFAIL);
+                goto L1;
+            case 1:
+                // Release empty pools to prevent bloat
+                minimize();
+                // Allocate new pool
+                pool = newPool(npages);
+                if (!pool)
+                    goto Lnomemory;
+                pn = pool.allocPages(npages);
+                assert(pn != OPFAIL);
+                goto L1;
+            case 2:
+                goto Lnomemory;
+            default:
+                assert(false);
+            }
+        }
+
+      L1:
+        pool.pagetable[pn] = B_PAGE;
+        if (npages > 1)
+            cstring.memset(&pool.pagetable[pn + 1], B_PAGEPLUS, npages - 1);
+        p = pool.baseAddr + pn * PAGESIZE;
+        cstring.memset(cast(char *)p + size, 0, npages * PAGESIZE - size);
+        debug (MEMSTOMP) cstring.memset(p, 0xF1, size);
+        //debug(PRINTF) printf("\tp = %x\n", p);
+        return p;
+
+      Lnomemory:
+        return null; // let mallocNoSync handle the error
+    }
+
+Se recuerda que la semántica de dicha función es la misma que la de la función
+``new_big()`` presentada en :ref:`dgc_algo_alloc`.
+
+Además, como se comentó en la sección anterior, los algoritmos en la
+implementación real están considerablemente menos modularizados que los
+presentados en la sección :ref:`dgc_algo`. Por ejemplo, la función
+``fullcollect()`` son 300 líneas de código.
 
-Soluciones Propuestas
 
-Para poder implementar un recolector de basura no conservativo es necesario
-disponer de un soporte de reflexión (en tiempo de compilación [DNG44607]_ y de
-ejecución [DNG29291]_) bastante completo . De otra forma es imposible
-distinguir si un área de memoria de la pila es utilizada como un puntero o como
-un simple conjunto de datos. D_ provee algún grado de reflexión, pero muy
-limitado como para poder obtener este tipo de información. Ya hay un plan para
-agregar mayores capacidades de reflexibilidad [DNG6842]_, y un pequeño avance
-en este sentido en la `versión 1.001`_, pero con algunos problemas [DNG6890]_
-[DNG6893]_.
-
-.. _`versión 1.001`: http://www.digitalmars.com/d/changelog.html#new1_001
+Memoria *encomendada*
+^^^^^^^^^^^^^^^^^^^^^
+Como se comentó en la sección anterior, diferenciar entre memoria
+*encomendada* de memoria *no-encomendada* es complejo y levemente costoso (en
+particular para sistemas operativos que no hacen esta distinción, al menos
+explícitamente, donde no hay ningún beneficio en realizar esta distinción).
+
+Incluso para Microsoft Windows, la ventaja de realizar esta distinción es
+discutible.
+
+
+Precisión
+^^^^^^^^^
+Este fue historicamente uno de los problemas principales del recolector de D_
+[NGD46407]_ [NGD35364]_. Sin embargo, desde que, en la versión 1.001, se ha
+incorporado la capacidad de marcar un bloque como de datos puros (no contiene
+punteros, el atributo ``NO_SCAN``) [NGA6842]_, la gravedad de esos problemas ha
+disminuído considerablemente, aunque siguieron reportándose problemas más
+esporádicamente [NGD54084]_ [NGL13744]_.
+
+De todas maneras queda mucho lugar para mejoras, y es un tema recurrente en el
+grupo de noticias de D_ y se han discutido formas de poder hacer que, al menos
+el *heap* sea preciso [NGD44607]_ [NGD29291]_. Además se mostro un interés
+general por tener un recolector más preciso [NGDN87831]_, pero no han habido
+avances al respecto.
+
+Otra forma de minimizar los efectos de la falta de precisión que se ha
+sugerido reiteradamente en el grupo es teniendo la
+posibilidad de indicar cuando no pueden haber punteros interiores a un bloque
+[NGD89394]_ [NGD71869]_. Esto puede ser de gran utilidad para objetos grandes
+y en particular para mejorar la implementación de de arreglos asociativos.
+
+
+Referencias débiles
+^^^^^^^^^^^^^^^^^^^
+El recolector actual no dispone de soporte de *referencias débiles*
+[#dgcweakref]_, sin embargo hay una demanda [NGD86840]_ [NGD13301]_ [NGL8264]_
+[NGD69761]_ [NGD74624]_ [NGD88065]_
 
-Se han propuesto otros métodos e implementaciones de recolector de basura, por
-ejemplo colectores con movimiento (*moving collectors*) [DNG42557]_ y conteo de
-referencias [DNG38689]_. Pero D_ es un lenguaje muy particular en cuanto a la
-recolección de basura (al permitir :ref:d_low_level hay muchas consideraciones
-a las que otros lenguajes no deben enfrentarse) y no es sencillo pensar en
-otras implementaciones sin hacer modificaciones de base al lenguaje.
+.. [#dgcweakref] Una referencia débil (o *weak reference* en inglés) es
+   aquella que que no protege al objeto referenciado de ser reciclado por el
+   recolector.
 
+Para cubrir esta demanda, se han implementado soluciones como biblioteca para
+suplir la inexistencia de una implementación oficial [NGA9103]_.
 
+Sin embargo éstas son en general poco robustas y extremadamente dependientes
+de la implementación del recolector y, en general, presentan problemas muy
+sutiles [NGD88065]_. Por esta razón se ha discutido la posibilidad de incluir
+la implementación de *referencias débiles* como parte del lenguaje
+[NGD88559]_.
 
-Problemas para Implementar Colectores con Movimiento
 
-El principal problema es la capacidad de D_ de manipular punteros y otras
-estructuras de bajo nivel, como uniones. O incluso la capacidad de interactuar
-con C. Al mover un objeto de un área de memoria a otro, es necesario actualizar
-todos los punteros que apuntan a éste. En D_ esta tarea no es trivial
-[DNG42564]_
+Concurrencia
+^^^^^^^^^^^^
+El soporte actual de concurrencia, en todos sus aspectos, es muy primitivo. El
+recolector apenas soporta múltiples *mutators* pero con un nivel de
+sincronización excesivo.
 
+Se ha sugerido en el pasado el uso de *pools* y listas de libres específicos
+de hilos, de manera de disminuir la contención, al menos para la asignación de
+memoria [NGD75952]_ [NGDN87831]_.
 
+Además se ha mostrado un interés por tener un nivel de concurrencia aún mayor
+en el recolector, para aumentar la concurrencia en ambientes *multi-core* en
+general pero en particular para evitar grandes pausas en programas con
+requerimientos de tiempo real, historicamente una de las principales críticas
+al lenguaje [NGDN87831]_ [NGL3937]_ [NGD22968]_ [NGA15246]_ [NGD5622]_
+[NGD2547]_ [NGD18354]_.
 
-Problemas para Implementar Conteo de Referencias
 
-Este tipo de recolectores reparten la carga de la recolección de forma uniforme
-a lo largo (y a la par) de la ejecución del programa. El problema principal
-para implementar este tipo de recolección es la necesidad de soporte en el
-compilador (cada asignación debe ser acompañada por el incremento/decremento de
-contadores de referencia), a menos que se implemente en una biblioteca. Por
-otro lado, características como el rebanado de arreglos (ver :ref:d_high_level)
-son difíciles de proveer con el conteo de referencias, entre otros problemas
-[DNG38704]_.
+Finalización
+^^^^^^^^^^^^
+El recolector actual no garantiza la finalización de objetos. En particular
+los objetos no son finalizados (es decir, no se llama a sus destructores)
+si aún alcanzables desde el *root set* cuando el programa termina. Cabe
+destacar que esto puede darse porque hay una referencia real desde el *root
+set* (en cuyo caso queda bajo el control del usuario) pero también, dado que
+el *root set* se visita de forma conservativa, se puede deber a un falso
+positivo, en cuyo caso la omisión de la finalización queda por completo fuera
+del control del usuario (y lo que es aún peor, el usuario no puede ser
+siquiera notificado de esta anomalía).
+
+Si bien la especificación de D_ no requiere esta capacidad (de hecho,
+rigurosamente hablando la especificación de D_ no garantiza la finalización de
+objetos bajo ninguna circunstancia), no hay mayores problemas para implementar
+un recolector que de este tipo de garantías [NGD88298]_.
+
+Además los objetos pueden ser finalizados tanto determinísticamente
+(utilizando ``delete`` o ``scope``; ver secciones :ref:`d_low_level`
+y :ref:`d_dbc`) como no deterministicamente (cuando son finalizados por el
+recolector). En el primer caso se puede, por ejemplo, acceder sus atributos
+u otra memoria que se conozca *viva*, mientras que en el segundo no. Sin
+embargo un destructor no puede hacer uso de esta distinción, haciendo que la
+finalización determinística tenga a fines prácticos las mismas restricciones
+que la finalización no deterministica. Es por esto que se ha sugerido permitir
+al destructor distinguir estos dos tipos de finalización [NGD89302]_.
+
+
+Eficiencia
+^^^^^^^^^^
+La eficiencia en general del recolector es una de las críticas frecuentes. Si
+bien hay muchos problemas que han sido resueltos, en especial por la inclusión
+de un mínimo grado de precisión en la versión 1.001, en la actualidad se
+siguen encontrando en el grupo de noticias críticas respecto a esto
+[NGD43991]_ [NGD67673]_ [NGD63541]_ [NGD90977]_.
+
+La principal causa de la ineficiencia del recolector actual es, probablemente,
+lo simple de su algoritmo principal de recolección. Más allá de una
+organización del *heap* moderadamente apropiada y de utilizar conjuntos de
+bits para la fase de marcado, el resto del algoritmo es casi la versión más
+básica de marcado y barrido. Hay mucho lugar para mejoras en este sentido.
+
+
+Detalles
+^^^^^^^^
+Finalmente hay varios detalles en la implementación actual que podrían
+mejorarse:
+
+Listas de libres:
+  hay 12 listas de libres, como para guardar bloques de tamaño de ``B_16``
+  a ``B_2048``, ``B_PAGE``, ``B_PAGEPLUS``, ``B_UNCOMMITTED`` y ``B_FREE``;
+  sin embargo solo tienen sentido los bloques de tamaño ``B_16`` a ``B_2048``,
+  por lo que 4 de esas listas no se utilizan.
+
+Conjuntos de bits:
+  los indicadores para la fase de marcado y otras propiedades de un bloque son
+  almacenados en conjuntos de bits que almacenan los indicadores de todos los
+  bloques de un *pool*. Como un *pool* tiene páginas con distintos tamaños de
+  bloque, se reserva una cantidad de bits igual a la mayor cantidad posible de
+  bloques que puede haber en el *pool*; es decir, se reserva 1 bit por cada 16
+  bytes del *pool*. Para un *pool* de 1 MiB (tamaño mínimo), teniendo en
+  cuenta que se utilizan 5 conjuntos de bits (``mark``, ``scan``, ``finals``,
+  ``freebits`` y ``noscan``), se utilizan 40 KiB de memoria para conjuntos de
+  bits (un 4% de *desperdicio* si, por ejemplo, ese *pool* estuviera destinado
+  por completo a albergar un solo objeto grande; lo que equivaldría al 2560
+  objetos de 16 bytes desperdiciados en bits inutilizados).
+
+Repetición de código:
+   Hay algunos fragmentos de código repetidos inecesariamente. Por ejemplo en
+   varios lugares se utilizan arreglos de tamaño variable que se implementan
+   repetidas veces (en general como un puntero al inicio del arreglo más el
+   tamaño actual del arreglo más el tamaño de la memoria total asignada
+   actualmente). Esto es propenso a errores y difícil de mantener.
+
+Uso de señales:
+   el recolector actual utiliza las señales del sistema operativo ``SIGUSR1``
+   y ``SIGUSR2`` para pausar y reanudar los hilos respectivamente. Esto
+   puede traer incovenientes a usuarios que desean utilizar estas
+   señales en sus programas (o peor aún, si interactúan con bibliotecas
+   de C que hacen uso de estas señales) [NGD5821]_.
 
 
 .. include:: links.rst
index 6eeac585f32ddd11a3b449753109cfa091a11c38..8960877aa6b28c686ed6fe05f905be602b6af765 100644 (file)
    Programming Problems, and Solutions, 1ra edición. Addison-Wesley
    Professional, 1999. ISBN 0-201-61562-2.
 
-.. [DNG46407] Oskar Linde. The problem with the D GC. Grupo de noticias
-   digitalmars.D, 8 de enero de 2007. `Mensaje número 46407`__.
-__ http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=46407
-
-.. [DNG43991] Andrey Khropov. [Performance] shootout.binarytrees when
-   implemented with gc is 10x slower than C# on .NET 2.0. Grupo de noticias
-   digitalmars.D, 11 de noviembre de 2006. `Mensaje número 43991`__.
-__ http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=43991
-
-.. [DNG35364] Frank Benoit. GC implementation. Grupo de noticias
-   digitalmars.D, 18 de marzo de 2006. `Mensaje número 35364`__.
-__ http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=35364
-
-.. [DNG44607] Russ Lewis. A TODO for somebody: Full Reflection Gets You
-   Smarter GC. Grupo de noticias digitalmars.D, 20 de noviembre de
-   2006. `Mensaje número 44607`__.
-__ http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=44607
-
-.. [DNG29291] Larry Evans. How does RTTI help gc?. Grupo de noticias
-   digitalmars.D, 21 de octubre de 2005. `Mensaje número 29291`__.
-__ http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=29291
-
-.. [DNG6842] Walter Bright. Transitioning to a type aware Garbage
-   Collector. Grupo de noticias digitalmars.D.announce, 22 de enero de
-   2007. `Mensaje número 6842`__.
-__ http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.announce&article_id=6842
-
-.. [DNG42557] Lionello Lunesu. Is a moving GC really needed?. Grupo de
-   noticias digitalmars.D, 2 de octubre de 2006. `Mensaje número 42557`__.
-__ http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=42557
-
-.. [DNG38689] Frank Benoit. GC, the simple solution. Grupo de noticias
-   digitalmars.D, 4 de junio de 2006. `Mensaje número 38689`__.
-__ http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=38689
-
-.. [DNG42564] xs0. Re: Is a moving GC really needed?. Grupo de noticias
-   digitalmars.D, 2 de octubre de 2006. `Mensaje número 42564`__.
-__ http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=42564
-
-.. [DNG38704] Walter Bright. Re: GC, the simple solution. Grupo de
-   noticias digitalmars.D, 4 de junio de 2006. `Mensaje número 38704`__.
-__ http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=38704
-
-.. [DNG6890] Lionello Lunesu. std.string.split is broken :( (Re: DMD 1.001
-   release). Grupo de noticias digitalmars.D.announce, 24 de enero de
-   2007. `Mensaje número 6890`__.
-__ http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.announce&article_id=6890
-
-.. [DNG6893] Oskar Linde. Re: DMD 1.001 release. Grupo de noticias
-   digitalmars.D.announce, 24 de enero de 2007. `Mensaje número 6893`__.
-__ http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.announce&article_id=6893
-
 .. [HDH03] Martin Hirzel, Amer Diwan, and Matthew Hertz, Proceedings
    of the 18th Conference on Object-Oriented Programming, Systems,
    Languages, and Applications (OOPSLA 2003), Anaheim, CA, Oct. 26-30,
@@ -143,6 +91,174 @@ __ http://www.mono-project.com/Compacting_GC
 __ http://www-plan.cs.colorado.edu/diwan/cbgc.pdf
 
 
+
+.. Grupo de noticias digitalmars.D:
+.. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. [NGD46407] Oskar Linde. The problem with the D GC. Grupo de noticias
+   digitalmars.D, 8 de enero de 2007. `Mensaje número 46407`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/The_problem_with_the_D_GC_46407.html
+
+.. [NGD54084] Babele Dunnit. Problems with GC, trees and array concatenation.
+   Grupo de noticias digitalmars.D, 1ro de junio de 2007. `Mensaje número
+   54084`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/Problems_with_GC_trees_and_array_concatenation_54084.html
+
+.. [NGD5821] Antonio Monteiro. Thread and gc.fullCollect. Grupo de noticias
+   digitalmars.D, 11 de enero de 2007. `Mensaje número 5821`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/learn/thread_and_gc.fullCollect_5821.html
+
+.. [NGD35364] Frank Benoit. GC implementation. Grupo de noticias
+   digitalmars.D, 18 de marzo de 2006. `Mensaje número 35364`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/35364.html
+
+.. [NGD71869] Fawzi Mohamed. large objects and GC. Grupo de noticias
+   digitalmars.D, 16 de mayo de 2008. `Mensaje número 71869`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/large_objects_and_GC_71869.html
+
+.. [NGD75952] Alan Knowles. Threading and the Garbage handler mess. Grupo de
+   noticias digitalmars.D, 6 de septiembre de 2008. `Mensaje número 75952`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/Threading_and_the_Garbage_handler_mess._75952.html
+
+.. [NGD13301] Pete Poulos. Weak references. Grupo de noticias digitalmars.D,
+   5 de agosto de 2008. `Mensaje número 13301`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/learn/weak_references_13301.html
+
+.. [NGD86840] Simon Treny. Keeping a list of instances and garbage-collection.
+   Grupo de noticias digitalmars.D, 29 de marzo de 2009. `Mensaje número
+   86840`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/Keeping_a_list_of_instances_and_garbage-collection_86840.html
+
+.. [NGD69761] Jarrett Billingsley. Weak references. Grupo de noticias
+   digitalmars.D, 12 de abril de 2008. `Mensaje número 69761`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/Weak_references._69761.html
+
+.. [NGD74624] Pete Poulos. Weak References. Grupo de noticias digitalmars.D,
+   6 de agosto de 2008. `Mensaje número 74624`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/Weak_References_74624.html
+
+.. [NGD88065] Jason House. D2 weak references. Grupo de noticias
+   digitalmars.D, 15 de abril de 2009. `Mensaje número 88065`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/D2_weak_references_88065.html
+
+.. [NGD88298] Leandro Lucarella. GC object finalization not guaranteed. Grupo
+   de noticias digitalmars.D, 18 de abril de 2009. `Mensaje número 88298`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/GC_object_finalization_not_guaranteed_88298.html
+
+.. [NGD44607] Russ Lewis. A TODO for somebody: Full Reflection Gets You
+   Smarter GC. Grupo de noticias digitalmars.D, 20 de noviembre de 2006.
+   `Mensaje número 44607`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/A_TODO_for_somebody_Full_Reflection_Gets_You_Smarter_GC_44607.html
+
+.. [NGD42557] Lionello Lunesu. Is a moving GC really needed? Grupo de noticias
+   digitalmars.D, 2 de octubre de 2006. `Mensaje número 425577`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/Is_a_moving_GC_really_needed_42557.html
+
+.. [NGD38689] Frank Benoit. GC, the simple solution. Grupo de noticias
+   digitalmars.D, 4 de junio de 2006. `Mensaje número 38689`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/38689.html
+
+.. [NGD29291] Larry Evans. How does RTTI help gc?. Grupo de noticias
+   digitalmars.D, 21 de octubre de 2005. `Mensaje número 29291`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/29291.html
+
+.. [NGD75995] David Simcha. Partially Static GC. Grupo de noticias
+   digitalmars.D, 9 de septiembre de 2008. `Mensaje número 75995`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/Partially_Static_GC_75995.html
+
+.. [NGD80695] David Simcha. Moving GC. Grupo de noticias digitalmars.D, 12 de
+   diciembre de 2008. `Mensaje número 80695`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/Moving_GC_80695.html
+
+.. [NGDN87831] Leandro Lucarella. Re: Std Phobos 2 and logging library? Grupo
+   de noticias digitalmars.D, 10 de abril de 2009. `Mensaje número 87831`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/Std_Phobos_2_and_logging_library_87794.html#N87831
+
+.. [NGD88559] Andrei Alexandrescu. -nogc. Grupo de noticias digitalmars.D, 23
+   de abril de 2009. `Mensaje número 88559`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/nogc_88559.html
+
+.. [NGD89394] David Simcha. Associative Arrays and Interior Pointers. Grupo de
+   noticias digitalmars.D, 4 de mayo de 2009. `Mensaje número 89394`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/Associative_Arrays_and_Interior_Pointers_89394.html
+
+.. [NGD89302] David Simcha. Destructors and Deterministic Memory Management.
+   Grupo de noticias digitalmars.D, 3 de mayo de 2009. `Mensaje número
+   89302`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/Destructors_and_Deterministic_Memory_Management_89302.html
+
+.. [NGD22968] Maxime Larose. GC pauses. Grupo de noticias digitalmars.D, 2 de
+   mayo de 2005. `Mensaje número 22968`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/22968.html
+
+.. [NGD5622] Christian Schüler. D and game programming. Grupo de noticias
+   digitalmars.D, 30 de mayo de 2002. `Mensaje número 5622`__.
+__ http://www.digitalmars.com/d/archives/5622.html
+
+.. [NGD2547] Mark T. Real time programming why not? Grupo de noticias
+   digitalmars.D, 5 de enero de 2002. `Mensaje número 2547`__.
+__ http://www.digitalmars.com/d/archives/2547.html
+
+.. [NGD26273] Stewart Gordon. Copying/heap compacting GC. Grupo de noticias
+   digitalmars.D, 24 de marzo de 2004. `Mensaje número 26273`__.
+__ http://www.digitalmars.com/d/archives/26273.html
+
+.. [NGD18354] Jarrett Billingsley. Does the GC ever perform a generational
+   collect? Grupo de noticias digitalmars.D, 5 de marzo de 2005. `Mensaje
+   número 18354`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/18354.html
+
+.. [NGD67673] Leonardo Maffi. Slow GC? Grupo de noticias digitalmars.D, 13 de
+   marzo de 2008. `Mensaje número 67673`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/Slow_GC_67673.html
+
+.. [NGD43991] Andrey Khropov. [Performance] shootout.binarytrees when
+   implemented with gc is 10x slower than C# on .NET 2.0. Grupo de noticias
+   digitalmars.D, 11 de noviembre de 2006. `Mensaje número 43991`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/Performance_shootout.binarytrees_when_implemented_with_gc_is_10x_slower_than_C_on_.NET_2.0_43991.html
+
+.. [NGD63541] Leonardo Maffi. A smaller GC benchmark. Grupo de noticias
+   digitalmars.D, 10 de diciembre de 2007. `Mensaje número 63541`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/A_smaller_GC_benchmark_63541.html
+
+.. [NGD90977] Anónimo. Why allocation of large amount of small objects so slow
+   (x10) in D? Grupo de noticias digitalmars.D, 21 de mayo de 2009. `Mensaje
+   número 90977`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/why_allocation_of_large_amount_of_small_objects_so_slow_x10_in_D_90977.html
+
+
+.. Grupo de noticias digitalmars.D.learn:
+.. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. [NGL13744] Alan Knowles. Any advice for GC/memory debugging. Grupo de
+   noticias digitalmars.D.learn, 1ro de septiembre de 2008. `Mensaje número
+   13744`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/learn/Any_advice_for_GC_memory_debugging_13744.html
+
+.. [NGL8264] Robert Fraser. Soft/weak references? Grupo de noticias
+   digitalmars.D.learn, 21 de junio de 2007. `Mensaje número 8264`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/learn/Soft_weak_references_8264.html
+
+.. [NGL3937] Chris K. GC and realtime threads. Grupo de noticias
+   digitalmars.D.learn, 12 de julio de 2006. `Mensaje número 3937`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/learn/3937.html
+
+
+.. Grupo de noticias digitalmars.D.announce:
+.. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. [NGA6842] Walter Bright. Transitioning to a type aware Garbage
+   Collector. Grupo de noticias digitalmars.D.announce, 22 de enero de
+   2007. `Mensaje número 6842`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/announce/Transitioning_to_a_type_aware_Garbage_Collector_6842.html
+
+.. [NGA9103] Myron Alexander. ANN: WeakObjectReference - class to hold weak
+   references. Grupo de noticias digitalmars.D.announce, 23 de junio de
+   2007. `Mensaje número 9103`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/announce/ANN_WeakObjectReference_-_class_to_hold_weak_references_9103.html
+
+.. [NGA15246] Mason Green. Blaze 2.0. Grupo de noticias
+   digitalmars.D.announce, 16 de marzo de 2009. `Mensaje número 15246`__.
+__ http://www.digitalmars.com/d/archives/digitalmars/D/announce/Blaze_2.0_15246.html
+
+
 .. include:: links.rst
 
 .. vim: set ts=3 sts=3 sw=3 et tw=78 :