Un efímero es una estructura de datos que resuelve dos problemas relacionados en los sistemas de recolección de basura . Por un lado, un efímero proporciona una notificación cuando un objeto está a punto de ser recolectado. Por otro lado, un efímero permite asociar datos a un objeto sin crear una referencia a ese objeto que impida su recolección. Un efímero es un par clave-valor, donde la clave es el objeto que el efímero protege, notificando al sistema cuando ese objeto es recolectable, y el valor puede ser cualquier dato asociado al objeto, como una lista de propiedades , que puede estar vacía. Dado que los elementos de la lista de propiedades pueden hacer referencia a la clave, pueden impedir la recolección de esa clave. Pero el recolector de basura trata al efímero de manera especial. El campo de valor no se rastrea hasta que se encuentra que la clave es accesible desde las raíces del sistema que no sean a través de las claves del efímero. El conjunto de efímeros cuyas claves solo son accesibles desde claves de efímero retienen claves que están listas para ser recolectadas; Estos objetos no son accesibles desde las raíces excepto a través de objetos efímeros. Cuando el recolector de basura detecta un conjunto de estos objetos, los efímeros se ponen en cola para su notificación y se rastrean sus claves y valores. Por lo tanto, los efímeros detectan los objetos que están listos para ser recolectados y rompen los ciclos que pueden impedir su recolección.
Descripción
En informática , la finalización se produce cuando un recolector de basura (GC) informa a una aplicación de que un objeto está "casi listo para ser recolectado". Se utiliza para ayudar a la aplicación a mantener sus invariantes . El recolector de basura puede usar referencias débiles para determinar qué objetos están casi listos para ser recolectados. Consideradas como pares clave-valor, la principal diferencia entre las referencias débiles y los efímeros radica en cómo los trata el recolector de basura. Para las referencias débiles, el recolector de basura siempre sigue el valor del par clave-valor. En cambio, para los efímeros, el recolector de basura no sigue el valor, sino que los pone en cola para su posterior observación en una segunda etapa: tras la primera fase de rastreo, recorre la cola examinando cada efímero y, si encuentra su clave, sigue su valor. Esta sutil diferencia tiene repercusiones en grafos con ciertos tipos de ciclos, donde los pares débiles no describen correctamente que un objeto debería estar "casi listo para ser recolectado". Por ejemplo, consideremos un par clave-valor con referencias débiles donde la clave es un objeto y el valor es un conjunto de propiedades asociadas al objeto. Se espera que cuando el objeto esté listo para ser recolectado, las propiedades también desaparezcan. Pero si el valor, posiblemente de forma transitiva, se mapea a su propia clave (el objeto), entonces el objeto nunca será recolectado. Si se utilizara un efímero en su lugar, el valor no se habría seguido a menos que se demostrara que el objeto seguía vivo, resolviendo así el ciclo. Los efímeros son similares a los pares débiles, pero un objeto en el campo clave de un efímero puede clasificarse como "casi recolectable" incluso si es accesible desde los campos de valor del efímero. [ 1 ]
Usos
Un efímero es un objeto que hace referencia fuerte a su contenido mientras la clave del efímero no sea recolectada por el recolector de basura, y débil a partir de entonces. Los efímeros resuelven un problema común al intentar "adjuntar" propiedades a objetos mediante un registro. Cuando se debe adjuntar una propiedad a un objeto, esta debería (en términos del comportamiento del recolector de basura) tener típicamente el tiempo de vida que tendría una variable de instancia de dicho objeto. Sin embargo, esto se complica al tener una asociación externa entre el objeto y su propiedad, como por ejemplo:
propiedad --------- registro --------- asociación --------- objeto
En este caso, el registro (un tercero) conservará la asociación, lo que requeriría su eliminación manual (en lugar de la recolección automática de basura). Si bien este problema siempre se puede resolver en cualquier situación concreta mediante el uso de uno de los diversos tipos de asociación débil, la elección del tipo de asociación "correcto" depende de varios factores, algunos de los cuales pueden cambiar dinámicamente.
Los efímeros resuelven este problema definiendo que el "contenido" (valor) de un efímero se mantendrá de forma segura hasta que se sepa que la clave ha sido eliminada por el recolector de basura. A partir de entonces, el contenido del efímero se mantendrá de forma débil. Por lo tanto, el contenido de un efímero puede ser eliminado por el recolector de basura solo si la clave es eliminable, que es el comportamiento exacto que observaríamos para una variable de instancia del objeto.
Historia
Los efemerones fueron inventados por primera vez por George Bosworth mientras trabajaba en Digitalk. [ 1 ] Se utilizaron como mecanismo de finalización en Visual Smalltalk Enterprise . Hoy en día, los efemerones están disponibles en la mayoría de los dialectos de Smalltalk , así como en muchos otros lenguajes con recolección automática de basura.
Ejemplos de uso
Charla informal
Varios dialectos de Smalltalk incluyen efímeros como características integradas o como paquetes adicionales. Por ejemplo, GNU Smalltalk [ 2 ] y Squeak . [ 3 ]
Lua
Lua no contiene una estructura de datos efímero independiente, pero sus estructuras de datos de tabla pueden configurarse para almacenar sus claves, valores o ambos de forma débil. Si las claves se almacenan de forma débil, pero los valores de forma fuerte, la tabla se comportará como un efímero. Lua 5.2 también introdujo el comportamiento de metatabla , que ayuda a construir estructuras de datos similares a efímeros. [ 4 ]
.NETO
Lenguajes como C# , F# y VB.NET , a partir de .NET Framework 4.0, tienen soporte en la clase ConditionalWeakTable . [ 5 ] El mecanismo subyacente de efímeros ( DependentHandle ) solía ser privado hasta .NET 6.
OCaml
En 2014 se presentó una implementación de un tipo efímero de OCaml [ 6 ] y se añadió a la biblioteca estándar en la versión 4.03. [ 7 ]
Raqueta
El dialecto Racket de Lisp admite efímeros en su sistema de ejecución . Allí, los efímeros se utilizan en combinación con asignaciones débiles para permitir que el recolector de basura libere pares clave-valor incluso si el valor contiene una referencia a una clave. [ 8 ]
Esquema SRFI
Una SRFI ( Scheme Request for Implementation ) define una API para efímeros para el lenguaje Scheme . [ 9 ] Sin embargo, no todas las implementaciones de Scheme admiten todas las SRFI.
Referencias
- 1 2 Barry Hayes (1997). "Ephemerones: Un nuevo mecanismo de finalización" . Lenguajes, programación, sistemas y aplicaciones orientados a objetos .
- ↑ "Objetos especiales - Guía del usuario de GNU Smalltalk" . Consultado el 20 de febrero de 2013 .
- ↑ "Efemérides" . Consultado el 20 de febrero de 2013 .
- ↑ "Manual de referencia de Lua 5.2, §2.5.2" . Consultado el 23 de mayo de 2025 .
- ↑ ".NET 4.0 - System.Runtime.CompilerServices.ConditionalWeakTable" . Blog de IKVM.NET . Archivado del original el 16 de octubre de 2013. Consultado el 14 de octubre de 2013 .
- ↑ Bobot, François. "Ephemerons meet OCaml GC" (PDF) . Taller de usuarios y desarrolladores de OCaml 2014. Archivado del original (PDF) el 19 de noviembre de 2016. Recuperado el 5 de abril de 2018 .
- ↑ Minsky, Yaron. "OCaml 4.03: Todo lo demás" . Blog de tecnología de Jane Street . Consultado el 5 de abril de 2018 .
- ↑ "15.2 Efemérones" . Consultado el 20 de febrero de 2013 .
- ↑ "SRFI-124: Efemerones" .
- Gestión automática de la memoria
- Estructuras del compilador