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