now*_*ed. 35 .net c# garbage-collection dispose
我今天和我的同事进行了一次对话,她说她刚刚了解了使用该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();
}
Run Code Online (Sandbox Code Playgroud)
我指出,除非GC决定这样做,否则该物体被标记为"可以处置"但实际上没有处理和垃圾收集.
她回答说,一旦using语句结束,对象将自动处理,因为using语句被转换为try-catch-finally块.因此,对象必须放在using语句的最后.
我对此感到困惑,因为我知道使用using
语句并不能保证对象被GC收集.所有发生的事情都是Dispose()
调用该方法.GC无论如何都决定GC.但当她要求证明时,我找不到任何证据.
有谁知道这是如何工作的,以及如何证明它?
Lua*_*aan 41
你在谈论两件截然不同的事情.
一旦using
-block结束,该对象将被释放.这并没有说什么时候它是垃圾收集.释放堆内存的唯一时间是发生垃圾收集 - 这只发生在内存压力下(除非您GC.Collect
明确使用).
处理对象只是意味着调用它的Dispose
方法.这通常意味着释放稀缺资源或本机资源(实际上,所有稀缺资源都是本机 - 套接字,文件......).现在,在您的情况下,一次性对象的生命周期在范围上是有限的,因此理论上可以在using
-block结束时立即收集- 但是,这在实践中并不真正发生,因为.NET运行时尝试避免收藏 - 它们很贵.因此,在跨越内存分配阈值之前,即使堆上有死对象,也不会发生任何集合.
那有什么意义Dispose
呢?与托管内存无关.你并不真正关心托管内存,你不应该期望Dispose
实际上会被调用 - 它不一定是.那唯一拥有由运行时调用是终结了,你就永远只能使用原生资源的配置-其实,有没有保证,如果仍然由时间存在,您有一个参考对象的终结器运行 - 那时托管内存可能已经被回收了.这就是你永远不会在终结器中处理托管资源的原因.
所以是的,她完全正确.关键是IDisposable
与垃圾收集器无关.处置并不意味着收集垃圾.
Sri*_*vel 12
她对钱的using
说法是正确的只是一个合成糖try/finally{obj.Dispose();}
.using
语句确保将丢弃对象.(将调用Dispose方法)但它与垃圾回收没有关系.
看看这个理解使用语句
简短的回答:所以现在我们知道using语句只是调用Dispose
而且除此之外什么都不做,请记住,Dispose
方法并不比任何其他方法特别.这只是一种方法而且就是这样.所以它与垃圾收集无关.有趣的是"垃圾收集器"甚至不知道Dispose
方法或IDisposable
.
希望这可以帮助
归档时间: |
|
查看次数: |
3157 次 |
最近记录: |