c# - example - ¿La palabra clave "usar" significa que el objeto es eliminado y sometido a GC?
implements idisposable dispose c# (2)
Ella tiene razón en el using
dinero. La declaración es solo un azúcar sintáctico para try/finally{obj.Dispose();}
. using
statement asegura que el objeto será eliminado. (Se llamará al método Dispose) pero no tiene relación con la recolección de basura.
Eche un vistazo a esta Understanding-the-using-statement
Respuesta corta: ahora sabemos que usar la declaración es simplemente llamar a Dispose
y no hace nada más que eso, y tenga en cuenta que el método Dispose
no es especial más que cualquier otro método. Es solo un método y eso es todo. Por lo tanto, no está relacionado con la recolección de basura. Curiosamente, "Garbage Collector" ni siquiera conoce el método Dispose
o IDisposable
.
Espero que esto ayude
Inicié una conversación con mi colega hoy, quien dijo que acababa de aprender la razón detrás de usar la declaración de using
.
//Using keyword is used to clean up resources that require disposal (IDisposable interface).
using (StreamReader reader = new StreamReader(@"C:/test.txt"))
{
string line = reader.ReadLine();
}
Señalé que el objeto está marcado como "Puede desecharse", pero que en realidad no se desecha ni recoge basura, a menos que GC decida hacerlo.
Ella respondió que el objeto se eliminará automáticamente una vez que termine el uso de la instrucción porque la instrucción de uso se traduce al bloque try-catch-finally. Por lo tanto, el objeto debe eliminarse al final de la instrucción de uso.
Estaba confundido por esto, porque sé que el uso de una declaración using
no garantiza que el objeto se recoja en GC. Todo lo que sucede es que se llamará al método Dispose()
. El GC decide cuándo GC, independientemente. Pero cuando ella pidió pruebas, no pude encontrar ninguna.
¿Alguien sabe cómo funciona esto y cómo probarlo?
Estás hablando de dos cosas muy diferentes.
El objeto se eliminará en cuanto finalice el using
bloque. Eso no dice nada sobre cuándo es basura recolectada. La única vez que se libera memoria de montón es cuando se produce una recolección de basura, que solo ocurre bajo la presión de la memoria (a menos que use GC.Collect
. GC.Collect
explícitamente).
Deshacer un objeto simplemente significa llamar a su método Dispose
. Eso a menudo significa liberar un recurso escaso o un recurso nativo (en la práctica, todos los recursos escasos son nativos: sockets, archivos, ...). Ahora, es útil que la vida útil del objeto desechable en su caso sea de alcance limitado, por lo que teóricamente podría recopilarse tan pronto como termine el using
bloque, sin embargo, eso realmente no sucede en la práctica, ya que el tiempo de ejecución de .NET trata de evitar las colecciones: son caros. Por lo tanto, hasta que cruce un umbral de asignación de memoria, no se realizará ninguna recopilación, aunque tenga un objeto muerto en el montón.
Entonces, ¿qué sentido tiene Dispose
? Nada que ver con la memoria administrada. En realidad, no le importa la memoria administrada, y no debe esperar que se llame a Dispose
, no tiene que ser así. Lo único que el tiempo de ejecución debe invocar es el finalizador, y solo puede usarlo para deshacerse de los recursos nativos; de hecho, no existe garantía de que los objetos a los que hace referencia sigan existiendo cuando se ejecuta el finalizador. - la memoria administrada ya podría haber sido reclamada por entonces. Es por eso que nunca maneja los recursos administrados en un finalizador.
Entonces sí, ella tenía toda la razón. El punto es que IDisposable
no tiene nada que ver con el recolector de basura. Dispuesto no significa basura recolectada.