正如其他人在这里所说GC是非确定性的,所以你不知道什么时候会收集你的对象.我要澄清的是,这不是内存的问题,而是系统资源(打开的文件,数据库连接),这些资源很昂贵,应该尽快发布.Dispose允许您在知道不再使用连接时执行此操作.如果它们没有及时发布,系统可能会耗尽这些资源,并且GC不知道这一点.这就是你必须手动完成的原因.
另外我想补充一点,使用'using'语句将以很好的方式为您完成.
正如其他人在这里所说GC是非确定性的,所以你不知道什么时候会收集你的对象.我要澄清的是,这不是内存的问题,而是系统资源(打开的文件,数据库连接),这些资源很昂贵,应该尽快发布.Dispose允许您在知道不再使用连接时执行此操作.如果它们没有及时发布,系统可能会耗尽这些资源,并且GC不知道这一点.这就是你必须手动完成的原因.
另外我想补充一点,使用'using'语句将以很好的方式为您完成.
垃圾收集在这里负责释放未使用的内存.
扩展GC以释放其他资源的原因有多种是有问题的.其中之一是终结器(在对象被垃圾收集时执行的方法)使得引用循环无法收集,除非您强烈限制从终结器中取消引用,这使得它们使用起来非常棘手.
另一个原因是大多数资源需要以某种及时的方式解除分配,这在依赖垃圾收集时是不可能的.
另一个原因是限制GC到内存管理涉及任何应用程序中的大量资源管理,以及几乎所有非有趣的资源管理.其他资源通常很有趣,值得一些额外的代码来明确它们的发布方式.
另一个原因是在某些应用程序中,GC使应用程序更快,因为它减少了为满足所有权语义而完成的复制量.这不是其他资源的问题.
其他人可以这样持续几个小时.
但是如果你不得不担心手动处理东西,那么GC有什么意义呢?!是不是GC在那里为编码器照顾这个?
问题是你不知道的时候,GC将运行.如果你的应用程序从不压力记忆,它可能根本不会运行.
假设我有这个代码:
class MonkeyGrabber : IDisposable { public MonkeyGrabber() { /* construction grabs a real, live monkey from the cage */ public void Dispose() { Dispose(true); /* releases the monkey back into the cage */ } // the rest of the monkey grabbing is left as an exercise to grad student drones } class MonkeyMonitor { public void CheckMonkeys() { if (_monkeyPool.GettingTooRowdy()) { MonkeyGrabber grabber = new MonkeyGrabber(); grabber.Spank(); } } }
现在,我的MonkeyMonitor检查猴子,如果它们太粗暴,它会获得一个宝贵的系统资源 - 一只猴子抓住系统上的爪子,用它抓住一只猴子并打它.由于我没有丢弃它,猴爪仍然抓住悬挂在其余笼子上方的猴子.如果剩下的猴子继续变得粗暴,我不能制作新的MonkeyGrabber,因为它仍然有帮助.哎呀.一个人为的例子,但你明白了:实现IDisposable的对象可能会占用有限的资源,应该及时发布.GC最终可能会放弃.
此外,还需要及时发布一些资源.我有一组类,如果在应用程序退出之前它们没有被应用程序或GC处理,将导致应用程序崩溃,因为它们来自的非托管资源管理器已经在GC到达它时已经消失了.
更多关于IDisposable.
使用是你的朋友 - 这是迄今为止我们与RAII最接近的.