stringtranslate.com

Recolección de basura (informática)

Recolección de basura para detener y copiar en una arquitectura Lisp : [1] La memoria se divide en memoria de trabajo y libre ; Se asignan nuevos objetos en el primero. Cuando está lleno (como se muestra), se realiza la recolección de basura: todas las estructuras de datos que aún están en uso se ubican mediante el rastreo del puntero y se copian en ubicaciones consecutivas en la memoria libre.
Después de eso, el contenido de la memoria de trabajo se descarta en favor de la copia comprimida, y se intercambian las funciones de memoria de trabajo y libre (como se muestra).

En informática , la recolección de basura ( GC ) es una forma de gestión automática de la memoria . El recolector de basura intenta recuperar la memoria asignada por el programa, pero ya no se hace referencia a ella; dicha memoria se llama basura . La recolección de basura fue inventada por el informático estadounidense John McCarthy alrededor de 1959 para simplificar la gestión manual de la memoria en Lisp . [2]

La recolección de basura libera al programador de realizar la administración manual de la memoria , donde el programador especifica qué objetos desasignar y devolver al sistema de memoria y cuándo hacerlo. [3] Otras técnicas similares incluyen asignación de pila , inferencia de región y propiedad de memoria, y combinaciones de las mismas. La recolección de basura puede tomar una proporción significativa del tiempo total de procesamiento de un programa y, como resultado, afectar el rendimiento .

Los recursos distintos de la memoria, como sockets de red , identificadores de bases de datos , ventanas , descriptores de archivos y descriptores de dispositivos, normalmente no se manejan mediante la recolección de basura, sino mediante otros métodos (por ejemplo, destructores ). Algunos de estos métodos también desasignan memoria.

Descripción general

Muchos lenguajes de programación requieren recolección de basura, ya sea como parte de la especificación del lenguaje (p. ej., RPL , Java , C# , D , [4] Go y la mayoría de los lenguajes de secuencias de comandos ) o de manera efectiva para una implementación práctica (p. ej., lenguajes formales como el cálculo lambda ) [ cita necesaria ] . Se dice que son lenguajes recolectados como basura . Otros lenguajes, como C y C++ , fueron diseñados para usarse con administración de memoria manual, pero tienen implementaciones disponibles con recolección de basura. Algunos lenguajes, como Ada , Modula-3 y C++/CLI , permiten que tanto la recolección de basura como la administración manual de memoria coexistan en la misma aplicación mediante el uso de montones separados para objetos recopilados y administrados manualmente. Otros, como D , se recolectan como basura pero permiten al usuario eliminar objetos manualmente o incluso desactivar la recolección de basura por completo cuando se requiere velocidad.

Aunque muchos lenguajes integran GC en su compilador y sistema de ejecución , también existen sistemas de GC post-hoc , como el Conteo Automático de Referencias (ARC). Algunos de estos sistemas de GC post-hoc no requieren recompilación. [5]

Ventajas

GC libera al programador de desasignar memoria manualmente. Esto ayuda a evitar algunos tipos de errores : [6]

Desventajas

GC utiliza recursos informáticos para decidir qué memoria liberar. Por lo tanto, la penalización por la conveniencia de no anotar manualmente la vida útil del objeto en el código fuente es una sobrecarga , que puede afectar el rendimiento del programa. [8] Un artículo revisado por pares de 2005 concluyó que GC necesita cinco veces más memoria para compensar esta sobrecarga y funcionar tan rápido como el mismo programa utilizando una gestión de memoria explícita idealizada. Sin embargo, la comparación se hace con un programa generado mediante la inserción de llamadas de desasignación utilizando un Oracle , implementado mediante la recopilación de seguimientos de programas ejecutados bajo un perfilador , y el programa solo es correcto para una ejecución particular del programa. [9] La interacción con los efectos de la jerarquía de la memoria puede hacer que esta sobrecarga sea intolerable en circunstancias que son difíciles de predecir o detectar en las pruebas de rutina. Apple dio el impacto en el rendimiento como una razón para no adoptar la recolección de basura en iOS , a pesar de ser la característica más deseada. [10]

El momento en el que realmente se recolecta la basura puede ser impredecible, lo que resulta en paradas (pausas para cambiar/liberar memoria) dispersas a lo largo de una sesión . Las paradas impredecibles pueden ser inaceptables en entornos en tiempo real , en el procesamiento de transacciones o en programas interactivos. Los recolectores de basura incrementales, concurrentes y en tiempo real abordan estos problemas, con diferentes compensaciones.

Estrategias

Rastreo

La recolección de basura de seguimiento es el tipo más común de recolección de basura, hasta el punto de que "recolección de basura" a menudo se refiere a la recolección de basura de seguimiento, en lugar de otros métodos como el recuento de referencias . La estrategia general consiste en determinar qué objetos deben ser recolectados como basura rastreando qué objetos son accesibles mediante una cadena de referencias desde ciertos objetos raíz, y considerar el resto como basura y recolectarlos. Sin embargo, existe una gran cantidad de algoritmos utilizados en la implementación, con características de complejidad y rendimiento muy variables.

Conteo de referencias

La recolección de basura con recuento de referencias es donde cada objeto tiene un recuento del número de referencias a él. La basura se identifica teniendo un recuento de referencia de cero. El recuento de referencias de un objeto aumenta cuando se crea una referencia a él y disminuye cuando se destruye una referencia. Cuando el recuento llega a cero, se recupera la memoria del objeto. [11]

Al igual que con la gestión manual de la memoria, y a diferencia de la recolección de basura de rastreo, el recuento de referencias garantiza que los objetos se destruyan tan pronto como se destruya su última referencia y, por lo general, solo accede a la memoria que se encuentra en las cachés de la CPU , en los objetos que se van a liberar o a las que apunta directamente. por aquellos y, por lo tanto, tiende a no tener efectos secundarios negativos significativos en el caché de la CPU y el funcionamiento de la memoria virtual .

El recuento de referencias presenta varias desventajas; Por lo general, esto puede resolverse o mitigarse mediante algoritmos más sofisticados:

Ciclos
Si dos o más objetos se refieren entre sí, pueden crear un ciclo en el que ninguno de ellos será recopilado, ya que sus referencias mutuas nunca permiten que sus recuentos de referencias lleguen a cero. Algunos sistemas de recolección de basura que utilizan recuento de referencias (como el de CPython ) utilizan algoritmos de detección de ciclos específicos para solucionar este problema. [12] Otra estrategia es utilizar referencias débiles para los "backpointers" que crean ciclos. En el recuento de referencias, una referencia débil es similar a una referencia débil en un recolector de basura de seguimiento. Es un objeto de referencia especial cuya existencia no incrementa el recuento de referencias del objeto de referencia. Además, una referencia débil es segura porque cuando el objeto de referencia se convierte en basura, cualquier referencia débil a él caduca , en lugar de permitirse que permanezca suspendida, lo que significa que se convierte en un valor predecible, como una referencia nula.
Espacio adicional (recuento de referencias)
El recuento de referencias requiere que se asigne espacio para que cada objeto almacene su recuento de referencias. El recuento puede almacenarse junto a la memoria del objeto o en una tabla lateral en algún otro lugar, pero en cualquier caso, cada objeto contado por referencia requiere almacenamiento adicional para su recuento de referencia. Para esta tarea se utiliza comúnmente espacio de memoria con el tamaño de un puntero sin firmar, lo que significa que se deben asignar 32 o 64 bits de almacenamiento de recuento de referencias para cada objeto. En algunos sistemas, es posible mitigar esta sobrecarga utilizando un puntero etiquetado para almacenar el recuento de referencias en áreas no utilizadas de la memoria del objeto. A menudo, una arquitectura en realidad no permite que los programas accedan a la gama completa de direcciones de memoria que podrían almacenarse en su tamaño de puntero nativo; cierto número de bits altos en la dirección se ignora o se requiere que sea cero. Si un objeto tiene de manera confiable un puntero en una ubicación determinada, el recuento de referencia se puede almacenar en los bits no utilizados del puntero. Por ejemplo, cada objeto en Objective-C tiene un puntero a su clase al comienzo de su memoria; en la arquitectura ARM64 que usa iOS 7 , se usan 19 bits no utilizados de este puntero de clase para almacenar el recuento de referencias del objeto. [13] [14]
Sobrecarga de velocidad (incremento/disminución)
En implementaciones ingenuas, cada asignación de una referencia y cada referencia que queda fuera del alcance a menudo requieren modificaciones de uno o más contadores de referencia. Sin embargo, en un caso común cuando se copia una referencia de una variable de alcance externo a una variable de alcance interno, de modo que la vida útil de la variable interna está limitada por la vida útil de la variable externa, se puede eliminar el incremento de referencia. La variable externa "posee" la referencia. En el lenguaje de programación C++, esta técnica se implementa y demuestra fácilmente con el uso de constreferencias. El recuento de referencias en C++ suele implementarse mediante " punteros inteligentes " [15] cuyos constructores, destructores y operadores de asignación gestionan las referencias. Se puede pasar un puntero inteligente por referencia a una función, lo que evita la necesidad de copiar y construir un nuevo puntero inteligente (lo que aumentaría el recuento de referencias al entrar en la función y disminuirlo al salir). En lugar de ello, la función recibe una referencia al puntero inteligente, que se fabrica de forma económica. El método Deutsch-Bobrow de recuento de referencias aprovecha el hecho de que la mayoría de las actualizaciones del recuento de referencias se generan a partir de referencias almacenadas en variables locales. Ignora estas referencias y solo cuenta las referencias en el montón, pero antes de que se pueda eliminar un objeto con un recuento de referencias cero, el sistema debe verificar con un escaneo de la pila y registrar que todavía no existe ninguna otra referencia. Se puede obtener una reducción sustancial adicional en los gastos generales de las actualizaciones de contadores mediante la fusión de actualizaciones introducida por Levanoni y Petrank . [16] [17] Considere un puntero que en un intervalo dado de ejecución se actualiza varias veces. Primero apunta a un objeto O1, luego a un objeto O2, y así sucesivamente hasta que al final del intervalo apunta a algún objeto On. Un algoritmo de recuento de referencias normalmente ejecutaría rc(O1)--, rc(O2)++, rc(O2)--, rc(O3)++, rc(O3)--, ..., rc(On)++. Pero la mayoría de estas actualizaciones son redundantes. Para evaluar correctamente el recuento de referencia al final del intervalo basta con realizar rc(O1)--y rc(On)++. Levanoni y Petrank midieron una eliminación de más del 99% de las actualizaciones de contadores en pruebas comparativas típicas de Java.
Requiere atomicidad
Cuando se utilizan en un entorno multiproceso , es posible que estas modificaciones (incremento y disminución) deban ser operaciones atómicas como comparar e intercambiar , al menos para cualquier objeto que se comparta o potencialmente se comparta entre varios subprocesos. Las operaciones atómicas son caras en un multiprocesador, y aún más caras si hay que emularlas con algoritmos de software. Es posible evitar este problema agregando recuentos de referencia por subproceso o por CPU y accediendo únicamente al recuento de referencia global cuando los recuentos de referencia locales sean o dejen de ser cero (o, alternativamente, utilizando un árbol binario de recuentos de referencia, o incluso renunciar a la destrucción determinista a cambio de no tener ningún recuento de referencia global), pero esto añade una importante sobrecarga de memoria y, por lo tanto, tiende a ser útil sólo en casos especiales (se utiliza, por ejemplo, en el recuento de referencias de los módulos del kernel de Linux). ). La fusión de actualizaciones de Levanoni y Petrank [16] [17] se puede utilizar para eliminar todas las operaciones atómicas de la barrera de escritura. Los subprocesos del programa nunca actualizan los contadores durante la ejecución del programa. Solo los modifica el recopilador, que se ejecuta como un único subproceso adicional sin sincronización. Este método se puede utilizar como mecanismo de parada del mundo para programas paralelos y también con un recopilador de recuento de referencias concurrente.
No en tiempo real
Las implementaciones ingenuas de recuento de referencias generalmente no proporcionan un comportamiento en tiempo real, porque cualquier asignación de puntero puede causar que una cantidad de objetos limitados solo por el tamaño total de la memoria asignada se liberen de forma recursiva mientras el subproceso no puede realizar otro trabajo. Es posible evitar este problema delegando la liberación de objetos sin referencia a otros subprocesos, a costa de una sobrecarga adicional.

Análisis de escape

El análisis de escape es una técnica en tiempo de compilación que puede convertir asignaciones de montón en asignaciones de pila , reduciendo así la cantidad de recolección de basura que se debe realizar. Este análisis determina si un objeto asignado dentro de una función es accesible fuera de ella. Si se descubre que una asignación local de función es accesible para otra función o subproceso, se dice que la asignación "escapa" y no se puede realizar en la pila. De lo contrario, el objeto puede asignarse directamente en la pila y liberarse cuando la función regrese, evitando el montón y los costos de administración de memoria asociados. [18]

Disponibilidad

En términos generales, es más probable que los lenguajes de programación de nivel superior tengan la recolección de basura como característica estándar. En algunos lenguajes que carecen de recolección de basura integrada, se puede agregar a través de una biblioteca, como con el recolector de basura Boehm para C y C++.

La mayoría de los lenguajes de programación funcionales , como ML , Haskell y APL , tienen la recolección de basura incorporada. Lisp es especialmente notable como el primer lenguaje de programación funcional y el primer lenguaje en introducir la recolección de basura. [19]

Otros lenguajes dinámicos, como Ruby y Julia (pero no Perl  5 o PHP anteriores a la versión 5.3, [20] que usan recuento de referencias), JavaScript y ECMAScript también tienden a usar GC. Los lenguajes de programación orientados a objetos como Smalltalk , RPL y Java suelen proporcionar recolección de basura integrada. Las excepciones notables son C++ y Delphi , que tienen destructores .

BÁSICO

BASIC y Logo a menudo han utilizado la recolección de basura para tipos de datos de longitud variable, como cadenas y listas, para no sobrecargar a los programadores con detalles de administración de memoria. En Altair 8800 , los programas con muchas variables de cadena y poco espacio de cadena podrían provocar pausas prolongadas debido a la recolección de basura. [21] De manera similar, el algoritmo de recolección de basura del intérprete Applesoft BASIC escanea repetidamente los descriptores de cadena en busca de la cadena que tiene la dirección más alta para compactarla hacia la memoria alta, lo que resulta en rendimiento [22] y hace pausas desde unos pocos segundos hasta unos minutos. [23] Un recolector de basura de reemplazo para Applesoft BASIC de Randy Wigginton identifica un grupo de cadenas en cada paso sobre el montón, lo que reduce drásticamente el tiempo de recolección. [24] BASIC.SYSTEM, lanzado con ProDOS en 1983, proporciona un recolector de basura de ventanas para BASIC que es muchas veces más rápido. [25]

C objetivo

Si bien Objective-C tradicionalmente no tenía recolección de basura, con el lanzamiento de OS X 10.5 en 2007 , Apple introdujo la recolección de basura para Objective-C  2.0, utilizando un recolector de tiempo de ejecución desarrollado internamente. [26] Sin embargo, con la versión 2012 de OS X 10.8 , la recolección de basura quedó obsoleta en favor del contador de referencia automático (ARC) de LLVM que se introdujo con OS X 10.7 . [27] Además, desde mayo de 2015 Apple incluso prohíbe el uso de recolección de basura para nuevas aplicaciones OS X en la App Store . [28] [29] Para iOS , la recolección de basura nunca se ha introducido debido a problemas en la capacidad de respuesta y el rendimiento de la aplicación; [10] [30] en cambio, iOS usa ARC. [31] [32]

Entornos limitados

La recolección de basura rara vez se utiliza en sistemas integrados o en tiempo real debido a la necesidad habitual de un control muy estricto sobre el uso de recursos limitados. Sin embargo, se han desarrollado recolectores de basura compatibles con muchos entornos limitados. [33] Microsoft .NET Micro Framework , .NET nanoFramework [34] y Java Platform, Micro Edition son plataformas de software integradas que, al igual que sus primos más grandes, incluyen recolección de basura.

Java

Los recolectores de basura disponibles en los JDK de Java incluyen:

Uso en tiempo de compilación

La recolección de basura en tiempo de compilación es una forma de análisis estático que permite reutilizar y recuperar la memoria en función de invariantes conocidas durante la compilación.

Esta forma de recolección de basura se ha estudiado en el lenguaje de programación Mercury , [36] y tuvo un mayor uso con la introducción del contador de referencia automático (ARC) de LLVM en el ecosistema de Apple (iOS y OS X) en 2011. [31] [32] [28]

Sistemas en tiempo real

Henry Baker y Henry Lieberman han desarrollado recolectores de basura incrementales, concurrentes y en tiempo real . [37] [38] [39]

En el algoritmo de Baker, la asignación se realiza en cualquiera de las mitades de una única región de memoria. Cuando llega a la mitad, se realiza una recolección de basura que mueve los objetos activos a la otra mitad y los objetos restantes se desasignan implícitamente. El programa en ejecución (el 'mutador') tiene que verificar que cualquier objeto al que hace referencia esté en la mitad correcta y, si no, moverlo, mientras una tarea en segundo plano busca todos los objetos. [40]

Los esquemas generacionales de recolección de basura se basan en la observación empírica de que la mayoría de los objetos mueren jóvenes. En la recolección de basura generacional se mantienen dos o más regiones de asignación (generaciones), que se mantienen separadas según la edad del objeto. Se crean nuevos objetos en la generación "joven" que se recopila periódicamente y, cuando una generación está llena, los objetos a los que todavía se hace referencia desde regiones más antiguas se copian en la siguiente generación más antigua. Ocasionalmente se realiza una exploración completa.

Algunas arquitecturas informáticas en lenguajes de alto nivel incluyen soporte de hardware para la recolección de basura en tiempo real.

La mayoría de las implementaciones de recolectores de basura en tiempo real utilizan el rastreo . [ cita necesaria ] Estos recolectores de basura en tiempo real cumplen con estrictas limitaciones de tiempo real cuando se usan con un sistema operativo en tiempo real. [41]

Ver también

Referencias

  1. ^ Abelson, Harold; Sussman, Gerald Jay; Sussman, Julie (2016). Estructura e interpretación de programas informáticos (PDF) (2ª ed.). Cambridge, Massachusetts, EE. UU.: MIT Press . págs. 734–736.
  2. ^ McCarthy, John (1960). "Funciones recursivas de expresiones simbólicas y su cálculo por máquina, Parte I". Comunicaciones de la ACM . 3 (4): 184-195. doi : 10.1145/367177.367199 . S2CID  1489409 . Consultado el 29 de mayo de 2009 .
  3. ^ "¿Qué es la recolección de basura (GC) en la programación?". Almacenamiento de búsqueda . Consultado el 17 de octubre de 2022 .
  4. ^ "Descripción general: lenguaje de programación D". dlang.org . Marte digital . Consultado el 29 de julio de 2014 .
  5. ^ "Recolección de basura - Lenguaje de programación D". dlang.org . Consultado el 17 de octubre de 2022 .
  6. ^ "Recolección de basura". rebelsky.cs.grinnell.edu . Consultado el 13 de enero de 2024 .
  7. ^ Microsoft . "Fundamentos de la recolección de basura | Microsoft Learn" . Consultado el 29 de marzo de 2023 .
  8. ^ Zorn, Benjamín (22 de enero de 1993). "El costo medido de la recolección de basura conservadora". Software: práctica y experiencia . Departamento de Ciencias de la Computación, Universidad de Colorado Boulder . 23 (7): 733–756. CiteSeerX 10.1.1.14.1816 . doi : 10.1002/spe.4380230704. S2CID  16182444. 
  9. ^ Hercios, Mateo; Berger, Emery D. (2005). "Cuantificación del rendimiento de la recolección de basura frente a la gestión explícita de la memoria" (PDF) . Actas de la vigésima conferencia anual ACM SIGPLAN sobre programación, sistemas, lenguajes y aplicaciones orientados a objetos - OOPSLA '05 . págs. 313–326. doi :10.1145/1094811.1094836. ISBN 1-59593031-0. S2CID  6570650. Archivado (PDF) desde el original el 2 de abril de 2012 . Consultado el 15 de marzo de 2015 .
  10. ^ ab "Inicio de herramientas para desarrolladores: sesión 300" (PDF) . WWDC 2011 . Apple, Inc. 24 de junio de 2011. Archivado desde el original (PDF) el 4 de septiembre de 2023 . Consultado el 27 de marzo de 2015 .
  11. ^ Microsoft . «Recolección de Basura por Conteo de Referencias» . Consultado el 29 de marzo de 2023 .
  12. ^ "Recuentos de referencias". Ampliación e incorporación del intérprete de Python . 2008-02-21 . Consultado el 22 de mayo de 2014 .
  13. ^ Ceniza, Mike. "Preguntas y respuestas del viernes 27 de septiembre de 2013: ARM64 y tú". mikeash.com . Consultado el 27 de abril de 2014 .
  14. ^ "Hamster Emporium: [explicación del objeto]: isa sin puntero". Sealiesoftware.com. 24 de septiembre de 2013 . Consultado el 27 de abril de 2014 .
  15. ^ Pibinger, Roland (3 de mayo de 2005) [17 de abril de 2005]. "RAII, objetos dinámicos y fábricas en C++".
  16. ^ ab Levanoni, Yossi; Petrank, Erez (2001). "Un recolector de basura con recuento de referencias sobre la marcha para Java". Actas de la 16ª Conferencia ACM SIGPLAN sobre programación, sistemas, lenguajes y aplicaciones orientados a objetos . OOPSLA 2001. págs. 367–380. doi :10.1145/504282.504309.
  17. ^ ab Levanoni, Yossi; Petrank, Erez (2006). "Un recolector de basura con recuento de referencias sobre la marcha para Java". Transmisión ACM. Programa. Lang. Sistema . 28 : 31–69. CiteSeerX 10.1.1.15.9106 . doi :10.1145/1111596.1111597. S2CID  14777709. 
  18. ^ Salagnac, Guillaume; Yovine, Sergio; Garbervetsky, Diego (24 de mayo de 2005). "Análisis de escape rápido para la gestión de memoria basada en regiones". Apuntes Electrónicos en Informática Teórica . 131 : 99-110. doi : 10.1016/j.entcs.2005.01.026 .
  19. ^ Chisnall, David (12 de enero de 2011). Lenguajes de programación influyentes, parte 4: Lisp.
  20. ^ "PHP: consideraciones de rendimiento". php.net . Consultado el 14 de enero de 2015 .
  21. ^ "Manual de referencia de Altair 8800 Basic 4.1" (PDF) . El archivo digital de tecnología vintage . Abril de 1977. p. 108. Archivado (PDF) desde el original el 29 de junio de 2021 . Consultado el 29 de junio de 2021 .
  22. ^ "Trabajé un poco para acelerar la recolección de basura de cadenas en Applesoft ..." Hacker News . Consultado el 29 de junio de 2021 .
  23. ^ Pequeño, Gary B. (1985). Dentro del Apple IIc. Bowie, Maryland: Brady Communications Co. p. 82.ISBN _ 0-89303-564-5. Consultado el 29 de junio de 2021 .
  24. ^ "Recolección rápida de basura". Llamar-APPLE : 40–45. Enero de 1981.
  25. ^ Vale la pena, Don (1984). Debajo de Apple Pro DOS (PDF) (edición impresa de marzo de 1985). Chatsworth, California, EE. UU.: Software de calidad. págs. 2–6. ISBN 0-912985-05-4. Archivado (PDF) desde el original el 3 de diciembre de 2008 . Consultado el 29 de junio de 2021 .
  26. ^ "Descripción general de Objective-C 2.0". Archivado desde el original el 24 de julio de 2010.
  27. ^ Siracusa, John (20 de julio de 2011). "Mac OS X 10.7 Lion: la revisión de Ars Technica".
  28. ^ ab "Apple dice que los fabricantes de aplicaciones Mac deben realizar la transición a la gestión de memoria ARC antes de mayo". AppleInsider . 2015-02-20.
  29. ^ Cichón, Waldemar (21 de febrero de 2015). "App Store: programa exclusivo de Apple con recolección de basura". Heise.de . Consultado el 30 de marzo de 2015 .
  30. ^ Silva, Preciosa (18 de noviembre de 2014). "iOS 8 frente a Android 5.0 Lollipop: Apple mata a Google con eficiencia de memoria". Tiempos de negocios internacionales . Archivado desde el original el 3 de abril de 2015 . Consultado el 7 de abril de 2015 .
  31. ^ ab Napier, Rob; Kumar, Mugunth (20 de noviembre de 2012). Programación de iOS 6 superando el límite. John Wiley e hijos . ISBN 978-1-11844997-4. Consultado el 30 de marzo de 2015 .
  32. ^ ab Cruz, José RC (22 de mayo de 2012). "Recuento automático de referencias en iOS". Doctor Dobbs . Archivado desde el original el 16 de mayo de 2020 . Consultado el 30 de marzo de 2015 .
  33. ^ Fu, Wei; Hauser, Carl (2005). "Un marco de recolección de basura en tiempo real para sistemas integrados". Actas del taller de 2005 sobre software y compiladores para sistemas integrados - SCOPES '05 . págs. 20-26. doi :10.1145/1140389.1140392. ISBN 1-59593207-0. S2CID  8635481.
  34. ^ "NanoFramework .NET".
  35. ^ Tene, Gil; Iyengar, Balaji; Lobo, Michael (2011). "C4: el recolector de compactación continuamente concurrente" (PDF) . ISMM '11: Actas del simposio internacional sobre gestión de la memoria . doi :10.1145/1993478. ISBN 978-1-45030263-0. Archivado (PDF) desde el original el 9 de agosto de 2017.
  36. ^ Mazur, Nancy (mayo de 2004). Recolección de basura en tiempo de compilación para el lenguaje declarativo Mercury (PDF) (Tesis). Universidad Católica de Lovaina . Archivado (PDF) desde el original el 27 de abril de 2014.
  37. ^ Huelsbergen, Lorenz; Winterbottom, Phil (1998). "Recolección de basura de marcado y barrido muy simultánea sin sincronización detallada" (PDF) . Actas del Primer Simposio Internacional sobre Gestión de la Memoria - ISMM '98 . págs. 166-175. doi :10.1145/286860.286878. ISBN 1-58113114-3. S2CID  14399427. Archivado (PDF) desde el original el 13 de mayo de 2008.
  38. ^ "Preguntas frecuentes sobre GC".
  39. ^ Liberman, Enrique; Hewitt, Carl (1983). "Un recolector de basura en tiempo real basado en la vida útil de los objetos". Comunicaciones de la ACM . 26 (6): 419–429. doi :10.1145/358141.358147. hdl : 1721.1/6335 . S2CID  14161480.
  40. ^ Panadero, Henry G. (1978). "Procesamiento de listas en tiempo real en una computadora serie". Comunicaciones de la ACM . 21 (4): 280–294. doi :10.1145/359460.359470. hdl : 1721.1/41976 . S2CID  17661259.ver también descripción
  41. ^ McCloskey; Tocino; Cheng; Grove (2008), Staccato: un recolector de basura compacto paralelo y concurrente en tiempo real para multiprocesadores (PDF) , archivado (PDF) desde el original el 11 de marzo de 2014.

Otras lecturas

enlaces externos