Saltar al contenido

Destruir manualmente objetos C#

Después de investigar con expertos en esta materia, programadores de deferentes ramas y maestros hemos dado con la respuesta al dilema y la dejamos plasmada en este post.

Solución:

No se destruyen manualmente los objetos .Net. De eso se trata ser un entorno gestionado.

De hecho, si el objeto es realmente accesible, lo que significa que tiene una referencia que puede usar para decirle al GC qué objeto desea destruir, será imposible recopilar ese objeto. El GC lo hará nunca recoger cualquier objeto que todavía es accesible.

lo que puedes hacer es llamar GC.Collect() para forzar una colección general. Sin embargo, esto casi nunca es una buena idea.

En su lugar, probablemente sea mejor simplemente pretender cualquier objeto que no use recursos no administrados y que no sea accesible para ningún otro objeto en su programa se destruye inmediatamente. Sé que esto no sucede, pero en este punto el objeto es solo un bloque de memoria como cualquier otro; no puede reclamarlo y eventualmente será recolectado, por lo que es posible que esté muerto para usted.

Una nota final sobre IDisposable. Solo debe usarlo para tipos que envuelven no administrado recursos: cosas como sockets, conexiones de bases de datos, objetos gdi, etc., y la suscripción ocasional de eventos/delegados.

Si no se puede acceder al objeto, puede llamar GC.Collect() y el objeto será destruido. El concepto de IDisposable no tiene nada que ver con CLR y es principalmente para que el código de usuario lo implemente para realizar adicional lógica de eliminación. Llamar a Dispose() en un objeto no liberará el objeto en sí mismo de la memoria, aunque es muy posible que elimine los recursos a los que hace referencia este objeto.

Debo agregar que si bien lo que dije es una forma de lograr esto, en el 99.9999% de las aplicaciones nunca debe llamar GC.Collect() porque a menudo degradar el rendimiento de su aplicación en lugar de mejorarlo.

Aunque puede desencadenar la recolección de basura (debe desencadenar GC para todas las generaciones porque no puede estar seguro de en qué generación se encuentra el objeto finalizable), no necesariamente puede forzar la finalización de un objeto en particular. Solo puede depender de suposiciones sobre cómo funciona el recolector de basura.

Además, dado que la finalización ocurre en su propio subproceso, debe llamar a WaitForPendingFinalizers después de activar la recolección de elementos no utilizados.

GC.Collect(GC.MaxGeneration);
GC.WaitForPendingFinalizers();

Como otros señalaron, esto puede dañar el rendimiento de su aplicación porque la invocación innecesaria del GC puede promover objetos de corta duración en generaciones más altas que son más costosas de recopilar y se recopilan con menos frecuencia.

En términos generales, una clase que implementa un finalizador (destructor) y no implementa IDisposable está mal vista. Y cualquier cosa que implemente IDisposable debería llamar a su lógica de finalizador y suprimirse de la finalización en la recolección de basura.

Jeff Richter publicó recientemente un pequeño truco agradable para recibir una notificación cuando se produce la recolección de basura.

Otro gran artículo sobre los conceptos básicos del recolector de basura y sugerencias de rendimiento por Rico Mariani (MSFT)

Te mostramos comentarios y calificaciones

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *