Métodos de finalización y destructores

Para la mayoría de los objetos que la aplicación crea, puede utilizar el recolector de elementos no utilizados de .NET Framework para realizar de forma implícita todas las tareas necesarias de administración de memoria. No obstante, cuando se crean objetos que encapsulan recursos no administrados, debe liberar explícitamente los recursos no administrados cuando la aplicación termine de utilizarlos. El tipo más habitual de recurso no administrado es un objeto que contiene un recurso del sistema operativo, como un archivo, ventana o conexión de red. Aunque el recolector de elementos no utilizados puede realizar el seguimiento de la duración de un objeto que encapsula un recurso no administrado, no tiene un conocimiento específico de cómo limpiar el recurso. Para estos tipos de objetos, .NET Framework proporciona el método Object.Finalize, que permite que un objeto limpie sus recursos no administrados correctamente cuando el recolector de elementos no utilizados reclama la memoria utilizada por el objeto. De forma predeterminada, el método Finalize no realiza ninguna acción. Si desea que el recolector de elementos no utilizados realice las operaciones de limpieza en el objeto antes de reclamar su memoria, debe reemplazar el método Finalize en su clase.

NotaNota

Para implementar el método Finalize en C#, se debe utilizar la sintaxis del destructor.En la versión 2.0 de .NET Framework, Visual C++ proporciona su propia sintaxis para implementar el método Finalize, tal y como se describe en Destructors and Finalizers in Visual C++.En las versiones 1.0 y 1.1 de .NET Framework, Visual C++ utilizó la sintaxis del destructor para el método Finalize, al igual que lo hace C#.

El recolector de elementos no utilizados realiza el seguimiento de los objetos que tienen métodos Finalize, utilizando una estructura interna denominada cola de finalización. Cada vez que la aplicación crea un objeto que tiene un método Finalize, el recolector de elementos no utilizados coloca una entrada en la cola de finalización que apunta a ese objeto. La cola de finalización contiene entradas para todos los objetos del montón administrado que necesitan que se llame a su código de finalización antes de que el recolector de elementos no utilizados reclame su memoria.

NotaNota

El ejemplo de código proporcionado para el método GC.KeepAlive muestra cómo la rigurosa recolección de elementos no utilizados puede hacer que se ejecute un finalizador mientras que un miembro del objeto reclamado todavía se está ejecutando y cómo utilizar el método KeepAlive para evitar esto.

Un método Finalize no debería producir excepciones porque la aplicación no puede controlarlo y puede hacer que la aplicación finalice.

Implementar destructores o métodos Finalize puede tener un impacto negativo en el rendimiento y por lo tanto debería evitar su uso innecesariamente. Reclamar la memoria que utilizan los objetos con métodos Finalize requiere al menos dos recolecciones de elementos no utilizados. Cuando el recolector de elementos no utilizados realiza una recolección, reclama la memoria de los objetos inaccesibles sin finalizadores. En este momento, no puede recolectar los objetos inaccesibles que tienen finalizadores. En su lugar, quita las entradas correspondientes a estos objetos de la cola de finalización, y las coloca en una lista de objetos marcados para finalizar. Las entradas de esta lista apuntan a los objetos del montón administrado que están listos para que se llame a su código de finalización. El recolector de elementos no utilizados llama a los métodos Finalize de los objetos de esta lista; a continuación, quita las entradas de la lista. Una recolección de elementos no utilizados posterior determinará que los objetos finalizados se han recolectado correctamente porque ninguna de las entradas de la lista de objetos marcados para finalizar apunta hacia ellos. En esta recolección de elementos no utilizados posterior, se reclama la memoria del objeto.

Vea también

Referencia

Finalize

Conceptos

Reemplazar el método Finalize

Sintaxis de destructores en C# y C++