¿Cuál es la relación entre GC, Finalize () y Dispose?

GC es para objetos administrados y Finalize es para objetos no administrados, eso es lo que he estado leyendo. Deshacer es implícito y Finalizar es explícito es lo que he estado leyendo. ¿Alguien puede darme un ejemplo de un módulo en el que las tres cosas se han utilizado por diferentes razones?

GC es una recolección de basura. Es la administración de memoria automática, que maneja la limpieza de los objetos asignados en el montón administrado. El .NET GC emplea un algoritmo de marca y barrido. Cuando se produce una recolección de basura, básicamente considera todos los objetos en la parte del montón a limpiar como recuperables. Luego pasa por un proceso de marcado donde escanea en busca de raíces. Es decir, identifica objetos que todavía están en uso por la aplicación. Una vez hecho esto, los objetos restantes son elegibles para la limpieza. El montón puede compactarse como parte de la limpieza.

Los métodos de disposición y finalizador ofrecen una opción para limpiar recursos, que GC no maneja. Por ejemplo, esto podría ser identificadores nativos y similares. No tienen nada que ver con reclamar memoria en el montón administrado.

Dispose debe llamarse explícitamente en un tipo que implemente IDisposable . Se puede invocar a través del método Dispose() mismo o mediante la construcción using . El GC no llamará a Dispose automáticamente.

Por otro lado, un finalizador o destructor (como lo llama la especificación del lenguaje) se llamará automáticamente en algún momento después de que el objeto sea elegible para la limpieza. Los métodos de finalización se ejecutan secuencialmente en un hilo dedicado.

Dispose() permite una limpieza determinista de los recursos, mientras que un finalizador puede actuar como una red de seguridad en caso de que el usuario no llame a Dispose() .

Si un tipo implementa un finalizador, la limpieza de las instancias se demora ya que se debe llamar al finalizador antes de la limpieza. Es decir, requerirá una recolección adicional para reclamar la memoria para instancias del tipo. Si el tipo implementa IDisposable también, se puede invocar el método Dispose y luego la instancia puede eliminarse de la finalización. Esto permitirá que el objeto se limpie como si no tuviera un finalizador.

Si quieres profundizar en esto, recomiendo CLR a través de C # por Jeffrey Richter . Es un gran libro y cubre todos los detalles sangrientos de esto (omití una serie de detalles). La 3ª edición acaba de ser lanzada.

Uno de los beneficios de .NET es el recolector de basura. En muchos idiomas, cada parte de la memoria debe ser administrada por el desarrollador, eventualmente cualquier memoria asignada debe ser liberada. En .NET (C #), el Garbage Collector (GC) se ocupará del proceso de liberar memoria para usted. Realiza un seguimiento del uso de sus objetos y, una vez que se vuelven “desarraigados” (es decir, no hay referencias directas o indirectas en su aplicación a ese objeto), la memoria del objeto se limpia automáticamente.

Deseche, o más particularmente, IDisposable y el patrón Dispose, se usa para manejar recursos por separado del GC. Algunos recursos deben ser limpiados explícitamente , por varias razones. Esto incluye el uso de una API “nativa” (donde .NET no sabe acerca de la memoria asignada), usando un recurso que envuelve identificadores nativos, etc. Para manejar esto limpiamente, implementa IDisposable y el patrón Dispose.

La finalización se produce en los objetos cuando están a punto de ser recogidos por el recolector de basura. Esto proporciona una “red de seguridad” donde un objeto que debería haber sido eliminado aún puede limpiarse, si es un poco más tarde que lo ideal. Al implementar un finalizador, puede garantizar que los recursos no administrados siempre se liberen.

El problema con la mayoría de las muestras es que existen múltiples razones para usar IDisposable, y la implementación adecuada varía según la razón por la que la está utilizando. Por ejemplo, si ajusta un recurso nativo directamente, debe implementar un finalizador, pero si encapsula otro tipo ID identificable, no es necesario un finalizador, aunque aún debe implementar IDisposable. Para abordar esto, he escrito sobre IDisposable y finalización en profundidad en mi blog , describiendo las múltiples razones por las que usaría IDisposable, y diferentes patrones por diferentes razones.

Es posible que desee leer lo que considero el artículo definitivo sobre IDisposable, finalizadores y recolección de basura, CLR Inside Out de Shawn Farkas : Indagar en IDisposable .

Este artículo deja muy pocas dudas sobre el tema.