3 ==========================
4 Recolección de basura en D
5 ==========================
12 :Autor: Leandro Lucarella (77891)
13 :Contacto: llucare@fi.uba.ar
14 :Autor: Tutora: Lic. Rosa Wachenchauzer
15 :Organización: Departamento de Computación, Facultad de Ingeniería
16 :Organización: Universidad de Buenos Aires
27 .. FIXME No me gusta como están redactados estos dos párrafos :S
29 Los lenguajes modernos tienen una tendencia cada vez más marcada a
30 adoptar técnicas cada vez más sofisticadas, haciéndolos más ricos y
31 convirtiéndolos realmente en lenguajes, no en meros preprocesadores que
32 convierten de una forma muy directa el código en assembly, permitiendo
33 construcciones semánticamente más ricas y permitiendo al programar una
34 mayor expresividad para plasmar algoritmos sin detenerse en los detalles
37 Estos conceptos supuestamente avanzados provienen, en general, de
38 lenguajes académicos (muchos de ellos funcionales) que implementan
39 estas funcionalidades hace mucho tiempo, pero que para su época o bien
40 no tuvieron suficiente difusión en el ambiente empresarial o bien eran
41 muy lentos por la baja capacidad de procesamiento de la época o eran
42 demasiado *revolucionarios* para ser adoptados por programadores que no
43 podían ver las ventajas que esos nuevos conceptos proveen.
45 El caso de la recolección de basura (*garbage collection* en inglés)
46 es uno de los más representativos. Lisp_ introdujo a principio de los
47 '60 el concepto de recolección de basura como un mecanismo para alocar
48 y liberar recursos de forma automática, pero no fue hasta avanzados los
49 '90 que esta técnica se empezó a utilizar en lenguajes de programación
50 de uso comercial, cuando fue popularizado por Java_. Incluso luego
51 de más de 30 años para Java_ era costosa la recolección de basura,
52 lo que sumado a la presencia de una máquina virtual para ejecutar los
53 programas producidos condujo a que estos sean notablemente lentos. Aún
54 así Java_ creció y entre las mejoras introducidas hubieron mejoras en
55 la recolección de basura. Otros lenguaje de programación populares que
56 utilizan alguna forma de recolección de basura son Python_, Ruby_, PHP_
60 El Lenguaje de Programación D_
61 ------------------------------
62 D_ es un lenguaje de programación joven. Nació en 1999 y el 2 de enero
63 de 2007 salió su `versión 1.0`_, aunque han quedado algunas cosas
64 importantes en el tintero. Su creador, `Walter Bright`_, desarrollador
65 principal de Zortech C++, el primer compilador de C++ a código nativo,
66 dice bien claro como nace el lenguaje, citando en su sitio web:
68 It seems to me that most of the "new" programming languages fall
69 into one of two categories: Those from academia with radical new
70 paradigms and those from large corporations with a focus on RAD and
71 the web. Maybe it's time for a new language born out of practical
72 experience implementing compilers.
74 Lo que podría traducirse como:
76 Parece que la mayoría de los lenguajes de programación "nuevos" caen
77 en 2 categorías: aquellos académicos con nuevos paradigmas radicales y
78 aquellos de grandes corporaciones con el foco en el desarrollo rápido
79 y web. Tal vez es hora de que nazca un nuevo lenguaje de la experiencia
80 práctica implementando compiladores.
82 D_ es un lenguaje de programación con sintáxis tipo C, multiparadigma,
83 compilado, con tipado fuerte y estático, con buenas capacidades tanto de
84 programación de bajo nivel (*system programming*) como de alto nivel. Y
85 este es tal vez el punto más fuerte de D, brindar lo mejor de los 2
86 mundos. Si bien tiene herramientas de muy bajo nivel, que por lo tanto
87 son muy propensas a errores, da una infinidad de mecanismos para evitar
88 el uso de estas herramientas a menos que sea realmente necesario.
89 Además pone mucho énfasis en la programación confiable, para lo cual
90 provee muchos mecanismos para detectar errores en los programas de forma
93 A continuación se enumeran las principales características de D_,
94 agrupadas por unidades funcional o paradigmas que soporta:
99 - Clases y funciones pueden ser parametrizadas.
100 - Instanciación implícita de funciones parametrizadas.
101 - Especialización parcial y explícita.
102 - Acepta tipos, valores y plantillas como parámetros.
103 - Acepta cantidad de parámetros variables.
104 - Soporta *mixins* [#dmixin]_.
105 - ``if`` estático (``static if``) [#dstaticif]_.
106 - Inferencia de tipos básica implícita [#dtypeinf]_ y explícita
107 (mediante ``typeof``) [#dtypeof]_.
108 - Expresiones ``is`` [#difexpr]_.
109 - Iteración sobre colecciones (``foreach``).
111 .. [#dmixin] *Mixin* tiene significados distintos en varios lenguajes de
112 programación. En D_ *mixin* significa tomar una secuencia arbitraria de
113 declaraciones e insertarla en el contexto (*scope*) actual. Esto puede
114 realizarse a nivel global, en clases, estructuras o funciones. Más
115 información en http://www.digitalmars.com/d/mixin.html
116 .. [#dstaticif] Esta construcción puede verse como similar a la
117 directiva del preprocesador de C/C++ ``#if``, pero a diferencia de
118 esto, en D_ el ``static if`` tiene acceso a todos los símbolos del
119 compilador (constantes, tipos, variables, etc). Más información
120 en http://www.digitalmars.com/d/version.html#staticif
121 .. [#dtypeinf] Si no se especifica un tipo al declarar una variable,
122 se infiere del tipo de su inicializador. Más información en
123 http://www.digitalmars.com/d/declaration.html#AutoDeclaration
124 .. [#dtypeof] ``typeof`` permite especificar un tipo
125 inferido de una expresión. Más información en
126 http://www.digitalmars.com/d/declaration.html#typeof
127 .. [#difexpr] Las *expresiones ``if``* permiten la compilación condicinal
128 basada en las características de un tipo. Esto se realiza en favor
129 a una técnica utilizada en C++ de realizar *pattern matching*
130 sobre los parámetros de las plantillas. Más información en
131 http://www.digitalmars.com/d/expression.html#IsExpression
134 Programación de Bajo Nivel (*system programming*)
135 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
136 - Compila a código de máquina nativo (no necesita una máquina virtual).
137 - Provee acceso a *assembly* (y por lo tanto, acceso directo al
140 - Soporta todos los tipos de C.
141 - ABI [#abi]_ compatible con C (genera archivos objeto estándar por lo que
142 se puede enlazar con código C).
143 - Permite manejo de memoria explícito (permitiendo alocar estructuras en
144 el *stack* o en el *heap*).
145 - Objetos *livianos* (no polimórficos) y arreglos *livianos* (estáticos,
146 sin *overhead* como C).
147 - La `programación genérica`_ permite realizar muchas optimizaciones
148 ya que se resuelve en tiempo de compilación y por lo tanto aumentando
149 la *performance* en la ejecución.
150 - Número de punto flotante de 80 bits.
151 - Control de alineación de miembros de una estructura.
153 .. [#abi] Interfaz de Aplicación Binaria (del inglés *Application Binary
157 Programación de Alto Nivel
158 ^^^^^^^^^^^^^^^^^^^^^^^^^^
159 - Manejo de memoria automática (recolección de basura).
160 - Sistema de módulos (similar a Python_).
161 - Funciones y delegados:
163 - Son ciudadanos de primera clase [#1stclasscity]_.
164 - Pueden ser sobrecargados.
165 - Pueden estar anidados.
166 - Argumentos de entrada/salida.
167 - Argumentos por omisión.
168 - Evaluación perezosa (*lazy*) de argumentos.
169 - Cantidad de argumentos variables (con tipado seguro).
171 - Arreglos *dinámicos* (de longitud variable) y arreglos asociativos
172 (también conocidos como *hashes* o diccionarios) y son ciudadanos
173 de primera clase [#1stclasscity]_, soporta rebanado (*array slicing*
174 [#dslicing]_) y chequeo de límites (*bound checking*).
175 - Soporta *strings* como tipo nativo (con codificación utf-8), incluyendo
176 la capacidad de hacer un ``switch`` sobre estos.
177 - ``alias`` [#dalias]_.
178 - Documentación embebida.
181 .. [#1stclasscity] Por ciudadano de primera clase se entiende que se
182 trata de un tipo soportado por completo por el lenguaje, disponiendo de
183 expresiones literales anónimas, pudiendo ser almacenados en variables,
184 estructuras de datos, teniendo una identidad intrínseca, más allá
185 de un nombre dado, etc. En realidad los arreglos asociativos no pueden
186 ser expresados como literales anónimos pero sí tienen una sintaxis
187 especial soportada directamente por el lenguaje.
188 .. [#dslicing] Se refiere a la capacidad de referirse a una porción de
189 un arreglo. Profundizaremos sobre esta característica más adelante
190 porque es importante a la hora de elegir un método de recolección
192 .. [#dalias] Análogo al ``typedef`` de C/C++.
195 Programación Orientada a Objetos
196 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
197 - Obejetos *pesadas* (polimórficos).
199 - Sobrecarga de operadores (con tipos de retorno covariantes [#dcovariant]_).
201 - Propiedades [#dprop]_.
203 .. [#dcovariant] Tipo de retorno covariante se refiere a la
204 capacidad de que una función sobreescrita por una clase derivada
205 puede retornar un tipo que sea derivado del tipo retornado
206 por la función original sobreescrita. Más información en
207 http://www.digitalmars.com/d/function.html
208 .. [#dprop] En D_ se refiere a funciones miembro que pueden ser tratadas
209 sintácticamente como campos de esa clase/estructura. Más información
210 en http://www.digitalmars.com/d/property.html#classproperties
213 Programación Confiable
214 ^^^^^^^^^^^^^^^^^^^^^^
215 - Diseño por contrato [#ddbc]_:
219 - Invariantes de representación.
220 - Afirmaciones (*asserts*).
223 - Orden de construcción estática (inicialización de módulos) determinado.
224 - Inicialización garantizada.
225 - RAII [#draii]_ (*Resource adquisition is initialization*).
226 - Guardias de contexto (*scope guards*).
227 - Excepciones (con ``try``, ``catch`` y ``finally``).
228 - Primitivas de sincronización de hilos (``synchronized``).
230 .. [#ddbc] El diseño por contrato es un concepto creado por Eiffel_ a
231 mediados/finales de los '80. Más información sobre el soporte de D_ en
232 http://www.digitalmars.com/d/dbc.html
233 .. [#draii] Es una técnica muy utilizada en C++ que consiste en reservar
234 recursos por medio de la construcción de un objeto y liberarlos cuando
235 se libera éste. Al llamarse al destructor de manera automática cuando
236 se sale del *scope*, se asegura que el recurso será liberado también.
237 Esta técnica es la base para desarrollar código seguro en cuanto a
238 excepciones (*exception-safe*) [SUTT99]_.
241 Importancia de la Recolección de Basura
242 ---------------------------------------
243 La recolección de basura es muchas veces vista por sus críticos de
244 una forma bastante *naive*. Muchas veces se argumenta que sólo es
245 útil para programadores descuidados o que su necesidad es sólo una
246 manifestación de un mal diseño. Si bien estas dos afirmaciones pueden
247 ser, en algunos casos, ciertas, es falaz pensar que ese es la única
248 ventaja de un recolector de basura. Uno de los aspectos más importantes
249 de un recolector de basura es lograr un mayor nivel de abstracción
250 [JOLI96]_. En particular, al diseñar o programar bibliotecas, de no
251 haber un recolector de basura, **la administración de memoria pasa a ser
252 parte de la interfaz de la biblioteca**. Y lo peor de este aspecto es
253 que muy pocas veces esto es tenido en cuenta, derivando en bibliotecas
254 muy difíciles de usar correctamente sin perder memoria, por no quedar
255 bien clara la responsabilidad del manejo de memoria.
257 Esto se debe a que, como se mencionó anteriormente, el manejo de memoria
258 es un *artefacto* proveniente del *hardware*, no un concepto propio
259 de los algoritmos a representar y como tal, nos impide desarrollar una
262 Muchas veces se aduce también que la recolección de basura impide
263 el desarrollo de programas eficientes. Si bien es inegable que la
264 recolección de basura impone una carga extra, ésta es, en la mayoría
265 de los casos, imperceptible. Incluso algunos algoritmos de recolección
266 de basura pueden aumentar la eficiencia en casos determinados, como
267 los recolectores que compactan, que pueden minimizar considerablemente
268 la cantidad de páginas de memoria referenciadas por el programa,
269 mejorando el *hit-ratio* tanto de la memoria virtual como del *cache*.
270 Aún si este no fuera el caso, o en casos de sistemas de tiempo real o
271 zonas muy críticas en cuanto a la eficiencia, muchas veces es posible
272 suspender el recolector de basura en dicho fragmento de código. Es
273 cierto que esto rompe un poco con la idea de ganar abstracción, pero
274 es necesario sólo en casos donde hay que realizar optimizaciones y las
275 optimizaciones son, en general, oscuras de por sí y tienden a perder
276 abstracción y a depender del *hardware* y otras particularidades.
278 El recolector de basura debe tener un comportamiento correcto y predecible
279 para que sea útil, si el programador no puede confiar en el recolector
280 de basura, éste se vuelve más un problema que una solución, porque
281 introduce nuevos puntos de falla en los programas, y lo que es peor,
282 puntos de falla no controlados por el programador, volviendo mucho más
283 difícil la búsqueda de errores.
288 Como se ha visto, D_ es un lenguaje de programación muy completo,
289 pero aún tiene algúnos aspectos inconclusos. Su recolector de basura
290 está en un estado de evolución muy temprana. Se trata de un marcado y
291 barrido (*mark and sweep*) conservativo que, en ciertas circunstancias,
292 no se comporta como es debido, ya que revisa toda la memoria del programa
293 en busca de referencias a objetos en el *heap* (en vez de revisar sólo
294 las partes que almacenan punteros). Esto produce que, en ciertos casos,
295 por ejemplo al almacenar arreglos de número o *strings* en la pila, el
296 recolector de basura se encuentre con *falsos positivos*, pensando que
297 un área del *heap* está siendo utilizada cuando en realidad el puntero
298 que hacía referencia a ésta no era tal. Este efecto puede llevar a la
299 pérdida de memoria masiva, llegando al límite de que eventualmente
300 el sistema operativo tenga que matar al programa por falta de memoria
301 [DNG46407]_. Aún cuando el programa no tenga estos problemas de por sí,
302 por usar datos que no pueden ser confundidos con direcciones de memoria,
303 este problema podría ser explotado por ataques de seguridad, inyectando
304 valores que sí sean punteros válidos y provocando el efecto antes
305 mencionado que deriva en la terminación abrupta del programa [DNG35364]_.
306 Finalmente, a estos problemas se suman los problemas de *performance*
309 Es difícil que D_ pueda ser un lenguaje de programación exitoso si
310 no provee un recolector de basura eficiente y que realmente evite la
311 pérdida masiva de memoria. Por otro lado, D_ podría atraer a una base de
312 usuarios mucho más amplia, si la gama de estrategias de recolección es
313 más amplia, pudiendo lograr adaptarse a más casos de uso sin llegar al
314 límite de tener que caer en el manejo explícito de memoria y perder por
315 completo las ventajas de la recolección de basura (con la consecuencia
316 ya mencionada de que el manejo de memoria tenga que pasar a ser parte
317 de las interfaces y la complejidad que esto agrega al diseño -y uso-
320 Soluciones Propuestas
321 ---------------------
322 Para poder implementar un recolector de basura no conservativo es
323 necesario disponer de un soporte de reflexión (en tiempo de compilación
324 [DNG44607]_ y de ejecución [DNG29291]_) bastante completo . De otra forma
325 es imposible distinguir si un área de memoria de la pila es utilizada
326 como un puntero o como un simple conjunto de datos. D_ provee algún
327 grado de reflexión, pero muy limitado como para poder obtener este
328 tipo de información. Ya hay un plan para agregar mayores capacidades
329 de reflexibilidad [DNG6842]_, y un pequeño avance en este sentido en la
330 `versión 1.001`_, pero con algunos problemas [DNG6890]_ [DNG6893]_.
332 Se han propuesto otros métodos e implementaciones de recolector de
333 basura, por ejemplo colectores con movimiento (*moving collectors*)
334 [DNG42557]_ y conteo de referencias [DNG38689]_. Pero D_ es un
335 lenguaje muy particular en cuanto a la recolección de basura (al
336 permitir `programación de bajo nivel (system programming)`_ hay muchas
337 consideraciones a las que otros lenguajes no deben enfrentarse) y no es
338 sencillo pensar en otras implementaciones sin hacer modificaciones de
341 Problemas para Implementar Colectores con Movimiento
342 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
343 El principal problema es la capacidad de D_ de manipular punteros y
344 otras estructuras de bajo nivel, como uniones. O incluso la capacidad
345 de interactuar con C. Al mover un objeto de un área de memoria a otro,
346 es necesario actualizar todos los punteros que apuntan a éste. En D_
347 esta tarea no es trivial [DNG42564]_
349 Problemas para Implementar Conteo de Referencias
350 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
351 Este tipo de recolectores reparten la carga de la recolección de forma
352 uniforme a lo largo (y a la par) de la ejecución del programa. El
353 problema principal para implementar este tipo de recolección es
354 la necesidad de soporte en el compilador (cada asignación debe ser
355 acompañada por el incremento/decremento de contadores de referencia), a
356 menos que se implemente en una biblioteca. Por otro lado, características
357 como el rebanado de arreglos (ver `Programación de Alto Nivel`_) son
358 difíciles de proveer con el conteo de referencias, entre otros problemas
364 De acuerdo al problema planteado, el objetivo de la presente trabajo
367 - Investigar y analizar la viabilidad de mejoras al recolector de
368 basura de D_, tanto mejoras menores dentro de las limitaciones actuales
369 del lenguaje (incluyendo pero no limitado a mejoras en el algoritmo
370 actual de recolección y soluciones en *espacio de usuario* -como
371 biblioteca-), como proponiendo mejoras al lenguaje que permitan la
372 implementación recolectores más precisos y eficientes.
373 - Elegir un conjunto de las mejores soluciones halladas e implementarlas.
374 Las soluciones que necesiten modificaciones en el lenguaje serán
375 implementadas modificando el compilador libre de D_ GDC_, que
376 también será utilizado como plataforma principal de desarollo y
377 prueba (debido a la disponibilidad completa del código fuente y
378 la libertad de usarlo y modificarlo libremente). De todas formas,
379 siempre se priorizarán las modificaciones al *frontend* [#frontend]_
380 sobre las modificaciones al *backend*, permitiendo así que las mejoras
381 puedan ser probadas eventualmente en otros compiladores que utilicen
382 el *frontend* publicado por DigitalMars_, como DMD_.
383 - Realizar pruebas sobre aplicaciones lo más variadas y reales posible
384 sobre todas las soluciones implementadas, de manera de determinar de
385 forma fehasible las ventajas de unas y otras en cuanto a latencia,
386 consumo de memoria, consumo de procesador, tiempos de pausa, etc.
387 - Presentar las conclusiones obtenidas del análisis y las pruebas
388 realizadas, tanto en el ámbito académico de la facultad como a la
389 comunidad de D_ (con el objetivo de sumar lo construido en este trabajo
392 .. [#frontend] El *frontend* es el módulo del compilador que realiza el
393 análisis sintáctico y semántico del lenguaje. GDC_ utiliza como
394 *frontend* el que provee libremente DigitalMars_.
395 .. [#backend] El *backend* es el módulo del compilador que emite
396 el código binario (o *assembly*, o el lenguaje que produzca el
397 compilador como resultado final). GDC utiliza el *backend* del GCC_
398 (*GNU Compiler Collection*), uno de los compiladores más populares.
402 Las ténicas de recolección de basura que se analizarán en este trabajo
403 incluirán, pero no se limitarán a:
405 - Conteo de referencia (*reference counting*).
406 - Marcado y compactado (*mark-compact*).
407 - Por copia (*copying collector*).
408 - Generacional (*generational garbage collector*).
411 Algunos ejemplos particulares de algoritmos a analizar son:
413 - VZOOM_ (*Virtually Zero Overhead Object Management*).
414 - CBGC_ (*Connectivity-based Garbage Collection*) [HDH03]_.
415 - Conteo de referencias perezoso en paralelo (*A New Multi-Processor
416 Architecture for Parallel Lazy Cyclic Reference Counting*) [LINS05]_.
418 Todo esto será analizado dentro del contexto, limitaciones y
419 requerimientos del lenguaje de programación D_. Del análisis realizado
420 se seleccionarán los algoritmos más viables para su implementación y
421 realizar pruebas reales para obtener resultados sobre su comportamiento,
422 en distintos escenarios de uso.
427 El trabajo se encontrará dividido en una serie de capítulos, los cuales se
428 describen brevemente a continuación:
431 Presenta el problema y temas a ser tratados en el trabajo.
433 Recolección de basura:
434 Introducción a la importancia de la recolección de basura y sus
435 principales técnicas, con sus ventajas y desventajas. También se da
436 un breve recorrido sobre el estado del arte.
438 Lenguaje de programación D:
439 Introducción y breve reseña del lenguaje de programación D. También
440 se presentan las necesidades particulares de D con respecto al
441 recolector de basura y su estado actual.
443 Definición del problema:
444 Describe más detalladamente los problemas actuales del recolector de
445 basura de D, sentando las bases para el análisis de los requerimientos
446 de recolección de basura en dicho lenguaje.
448 Análisis de la solución:
449 Describe los resultados del análisis y explica los fundamentos para
450 elegir los algoritmos seleccionados para implementar, en base a los
451 requerimientos hallados anteriormente.
453 Implementación de la solución:
454 Describe el diseño e implementación de los algoritmos
455 seleccionados. Se detalla si la solución se implementa como
456 biblioteca o si fue necesario modificar el compilador y de ser así
457 si se modificó el *frontend* o el GDC y se comentan problemas y
458 limitaciones encontradas.
461 Se presentan las conclusiones del trabajo, comparando los resultados
462 obtenidos con el punto de partida. Se mencionan puntos pendientes o
463 nuevas líneas de investigación.
468 ========================================== ======== ======== ========
469 Actividad Esfuerzo Inicio Fin
470 ========================================== ======== ======== ========
471 Investigación y definición de objetivos 176 hs Feb 2006 Dic 2006
472 Confección del documento de propuesta 48 hs Ene 2007 Feb 2007
473 Análisis de las posibles soluciones 96 hs Dic 2006 May 2007
474 Desarrollo de las soluciones elegidas 240 hs Abr 2007 Dic 2007
475 Confección de la Tesis 240 hs Sep 2007 Dic 2007
476 Confección del material para la exposición 52 hs Nov 2007 Dic 2007
477 ========================================== ======== ======== ========
480 Tanto las horas de esfuerzo como las fechas de inicio y fin son
481 tentativas y por lo tanto aproximadas. Debido a la finalización de la
482 cursada al término del primer cuatrimestre de 2007, la dedicación
483 aumentará considerablemente durante el segundo cuatrimestre de 2007 (por
484 ello la diferencia de horas entre ambos períodos).
490 .. |date| date:: %e de %B de %Y
493 .. _Lisp: http://www.lisp.org/
494 .. _Java: http://www.java.com/
495 .. _Python: http://www.python.org/
496 .. _Ruby: http://www.ruby-lang.org/
497 .. _PHP: http://www.php.net/
498 .. _`C#`: http://www.ecma-international.org/publications/standards/Ecma-334.htm
499 .. _D: http://www.digitalmars.com/d/
500 .. _`versión 1.0`: http://www.digitalmars.com/d/changelog2.html#new1_00
501 .. _`versión 1.001`: http://www.digitalmars.com/d/changelog.html#new1_001
502 .. _`Walter Bright`: http://www.walterbright.com/
503 .. _Eiffel: http://www.eiffel.com/
504 .. _GDC: http://dgcc.sourceforge.net/
505 .. _DigitalMars: http://www.digitalmars.com/
506 .. _DMD: http://www.digitalmars.com/d/dcompiler.html
507 .. _GCC: http://gcc.gnu.org/
508 .. _`Mensaje número 46407`: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=46407
509 .. _`Mensaje número 43991`: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=43991
510 .. _`Mensaje número 35364`: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=35364
511 .. _`Mensaje número 44607`: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=44607
512 .. _`Mensaje número 29291`: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=29291
513 .. _`Mensaje número 6842`: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.announce&article_id=6842
514 .. _`Mensaje número 42557`: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=42557
515 .. _`Mensaje número 38689`: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=38689
516 .. _`Mensaje número 42564`: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=42564
517 .. _`Mensaje número 38704`: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=38704
518 .. _`Mensaje número 6890`: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.announce&article_id=6890
519 .. _`Mensaje número 6893`: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.announce&article_id=6893
520 .. _CBGC: http://www.cs.colorado.edu/%7Ediwan/cbgc.pdf
521 .. _VZOOM: http://home.comcast.net/~vzoom/
524 .. [JOLI96] Richard Jones, Rafael D Lins. Garbage Collection: Algorithms
525 for Automatic Dynamic Memory Management. John Wiley & Sons, 1996.
527 .. [SUTT99] Herb Sutter. Exceptional C++: 47 Engineering Puzzles,
528 Programming Problems, and Solutions, 1ra edición. Addison-Wesley
529 Professional, 1999. ISBN 0-201-61562-2.
530 .. [DNG46407] Oskar Linde. The problem with the D GC. Grupo de noticias
531 digitalmars.D, 8 de enero de 2007. `Mensaje número 46407`_.
532 .. [DNG43991] Andrey Khropov. [Performance] shootout.binarytrees when
533 implemented with gc is 10x slower than C# on .NET 2.0. Grupo de noticias
534 digitalmars.D, 11 de noviembre de 2006. `Mensaje número 43991`_.
535 .. [DNG35364] Frank Benoit. GC implementation. Grupo de noticias
536 digitalmars.D, 18 de marzo de 2006. `Mensaje número 35364`_.
537 .. [DNG44607] Russ Lewis. A TODO for somebody: Full Reflection Gets You
538 Smarter GC. Grupo de noticias digitalmars.D, 20 de noviembre de
539 2006. `Mensaje número 44607`_.
540 .. [DNG29291] Larry Evans. How does RTTI help gc?. Grupo de noticias
541 digitalmars.D, 21 de octubre de 2005. `Mensaje número 29291`_.
542 .. [DNG6842] Walter Bright. Transitioning to a type aware Garbage
543 Collector. Grupo de noticias digitalmars.D.announce, 22 de enero de
544 2007. `Mensaje número 6842`_.
545 .. [DNG42557] Lionello Lunesu. Is a moving GC really needed?. Grupo de
546 noticias digitalmars.D, 2 de octubre de 2006. `Mensaje número 42557`_.
547 .. [DNG38689] Frank Benoit. GC, the simple solution. Grupo de noticias
548 digitalmars.D, 4 de junio de 2006. `Mensaje número 38689`_.
549 .. [DNG42564] xs0. Re: Is a moving GC really needed?. Grupo de noticias
550 digitalmars.D, 2 de octubre de 2006. `Mensaje número 42564`_.
551 .. [DNG38704] Walter Bright. Re: GC, the simple solution. Grupo de
552 noticias digitalmars.D, 4 de junio de 2006. `Mensaje número 38704`_.
553 .. [DNG6890] Lionello Lunesu. std.string.split is broken :( (Re: DMD 1.001
554 release). Grupo de noticias digitalmars.D.announce, 24 de enero de
555 2007. `Mensaje número 6890`_.
556 .. [DNG6893] Oskar Linde. Re: DMD 1.001 release. Grupo de noticias
557 digitalmars.D.announce, 24 de enero de 2007. `Mensaje número 6893`_.
558 .. [HDH03] Martin Hirzel, Amer Diwan, and Matthew Hertz, Proceedings
559 of the 18th Conference on Object-Oriented Programming, Systems,
560 Languages, and Applications (OOPSLA 2003), Anaheim, CA, Oct. 26-30,
562 .. [LINS05] Rafael D Lins. A New Multi-Processor Architecture for
563 Parallel Lazy Cyclic Reference Counting. Proceedings of the 17th
564 International Symposium on Computer Architecture on High Performance
565 Computing - Volume 00 (páginas 35-43), 2005.
567 .. vim: set ts=2 sts=2 sw=2 et tw=75 :