Sí, el recolector de basura está liberando sus objetos cuando no se usan más.
lo que usualmente llamamos una pérdida de memoria en .NET es más como:
- Usted está utilizando recursos externos (que no son basura recogida) y el olvido para liberarlos. Esto se resuelve generalmente implementando la interfaz IDisposable.
- le parece que no son referencias a un objeto dado, pero de hecho hay, en algún lugar y no se están usando más sobre ellos, pero el recolector de basura no sabe nada de ellos.
Además, la memoria solo se recupera cuando es necesario, lo que significa que el recolector de basura se activa en momentos determinados y realiza una recopilación que determina qué memoria se puede liberar y liberar. Hasta que lo haga, la memoria no se reclama, por lo que podría parecer que la memoria se está perdiendo.
aquí, creo que voy a ofrecer una respuesta más compleja sólo para aclarar.
Primero, el recolector de basura se ejecuta en su propio hilo.Debe comprender que, para recuperar memoria, el recolector de basura necesita detener todos los otros hilos para poder seguir la cadena de referencia y determinar qué depende de qué. Esa es la razón por la que la memoria no se libera de inmediato, un recolector de basura implica ciertos costos en el rendimiento.
Internamente, el recolector de basura administra la memoria en generaciones. De manera muy simplificada, hay varias generaciones para objetos de larga vida, vida corta y gran tamaño. El recolector de basura mueve el objeto de una generación a otra cada vez que realiza una colección, que ocurre más a menudo para la generación efímera que la de larga duración. También reasigna objetos para obtener el espacio contiguo más posible, así que de nuevo, realizar una colección es un proceso costoso.
Si realmente desea ver los efectos de liberar el formulario (al salir del alcance y sin tener más referencias) puede llamar al GC.Collect()
. Haga eso solo para probar, es muy imprudente llamar a Collect, excepto en unos pocos casos donde sabe exactamente lo que está haciendo y las implicaciones que tendrá.
Un poco más de explicación sobre el método Dispose de la interfaz IDispose.
Dispose no es un destructor en la forma habitual de C++, no es un destructor en absoluto. Dispose es una forma de eliminar deterministamente los objetos no administrados. Un ejemplo: suponga que llama a una biblioteca COM externa que asigna 1GB de memoria debido a lo que está haciendo. Si no tiene Dispose, la memoria se quedará allí, desperdiciando espacio hasta que el GC inice una colección y recupere la memoria no administrada llamando al destructor de objetos real. Entonces, si desea liberar la memoria de inmediato, debe llamar al método Dispose, pero no está "forzado" a hacerlo.
Si no utiliza la interfaz IDisposable, debe liberar sus recursos no administrados en el método Finalize. Finalize se llama automáticamente desde el destructor de objetos cuando el GC intenta reclamar el objeto. Entonces, si tiene un método de finalización adecuado, la memoria no administrada se liberará de cualquier forma. Calling Dispose solo lo hará determinista.
¿Cómo sabe que la memoria tiene una fuga? – Dmitry
Estaba siguiendo la memoria en el Administrador de tareas. Ver los otros dos comentarios que hice a continuación. Tal vez no es una "fuga" pero es molesto, no obstante. – Procule
@Procule - Te preocupes si el CLR GC funciona. Lo hace. Muchos codificadores C/C++ lo usan y están muy contentos con él. Sin embargo, debe aprender sobre el uso de/IDisposable pattern, y verificar los documentos y ver si un objeto implementa IDisposable. Pero la gran ventaja de .NET no es microgestionar este tipo de cosas. – overslacked