]> git.llucax.com Git - z.facultad/75.00/propuesta.git/blob - propuesta.rst
Remove a vim swap file.
[z.facultad/75.00/propuesta.git] / propuesta.rst
1
2 ==========================
3 Recolección de basura en D
4 ==========================
5
6
7 ------------------
8 Propuesta de Tesis
9 ------------------
10
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
16 :Fecha: |date|
17 :Revisión: 3
18 :Estado: Borrador
19
20
21 .. contents::
22
23
24 Introducción
25 ============
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
32 del *hardware*.
33
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.
41
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_
54 y `C#`_, entre otros.
55
56
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:
64
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.
70
71 Lo que podría traducirse como:
72
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.
78
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
88 temprana.
89
90 A continuación se enumeran las principales características de D_,
91 agrupadas por unidades funcional o paradigmas que soporta:
92
93
94 Programación Genérica
95 ^^^^^^^^^^^^^^^^^^^^^
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``).
107
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
129
130
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
135   *hardware*).
136 - ``goto``.
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.
149
150 .. [#abi] Interfaz de Aplicación Binaria (del inglés *Application Binary
151    Interface*).
152
153
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:
159
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).
167
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.
176 - Números complejos.
177
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
188    de basura.
189 .. [#dalias] Análogo al ``typedef`` de C/C++.
190
191
192 Programación Orientada a Objetos
193 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
194 - Objetos *pesadas* (polimórficos).
195 - Interfaces.
196 - Sobrecarga de operadores (con tipos de retorno covariantes [#dcovariant]_).
197 - Clases anidadas.
198 - Propiedades [#dprop]_.
199
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
208
209
210 Programación Confiable
211 ^^^^^^^^^^^^^^^^^^^^^^
212 - Diseño por contrato [#ddbc]_:
213
214   - Precondiciones.
215   - Postcondiciones.
216   - Invariantes de representación.
217   - Afirmaciones (*asserts*).
218
219 - Pruebas unitarias.
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``).
226
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]_.
236
237
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.
253
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
257 mayor abstracción.
258
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.
274
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.
281
282
283 Problema
284 ========
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*
304 [DNG43991]_.
305
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-
315 de una biblioteca).
316
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]_.
328
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
336 base al lenguaje.
337
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]_
345
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
356 [DNG38704]_.
357
358
359 Objetivo
360 ========
361 De acuerdo al problema planteado, el objetivo de la presente trabajo
362 será:
363
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
387   al lenguaje).
388
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.
396
397 Alcance
398 -------
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:
401
402 - Conteo de referencia (*reference counting*).
403 - Marcado y compactado (*mark-compact*).
404 - Por copia (*copying collector*).
405 - Generacional (*generational garbage collector*).
406 - Técnicas híbridas.
407
408 Algunos ejemplos particulares de algoritmos a analizar son:
409
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]_.
414
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.
420
421
422 Organización
423 ============
424 El trabajo se encontrará dividido en una serie de capítulos, los cuales se
425 describen brevemente a continuación:
426
427 Introducción:
428   Presenta el problema y temas a ser tratados en el trabajo.
429
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.
434
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.
439
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.
444
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.
449
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.
456
457 Conclusiones:
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.
461
462
463 Cronograma
464 ==========
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 ========================================== ======== ======== ========
475
476
477 .. ============== FIN DOCUMENTO ===========
478
479 .. Macros:
480 .. |date| date:: %e de %B de %Y
481
482 .. Links:
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/
512
513 .. Citas:
514 .. [JOLI96] Richard Jones, Rafael D Lins. Garbage Collection: Algorithms
515    for Automatic Dynamic Memory Management. John Wiley & Sons, 1996.
516    ISBN 0-471-94148-4.
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,
551    2003.
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.
556
557 .. vim: set ts=2 sts=2 sw=2 et tw=75 :