什么是垃圾收集器的意义

3 .net garbage-collection

SqlConnection connection = new SqlConnection(FROM_CONFIGURATION) 
SqlCommand command = new SqlCommand("SomeSQL", connection); 
connection.Open(); 
command.ExecuteNonQuery(); 
command.Dispose(); 
connection.Dispose();
Run Code Online (Sandbox Code Playgroud)

建议上面的代码应该包含try/catch(或using),这样如果抛出异常,所有资源都会正确处理.

但是如果你不得不担心手动处理东西,那么GC有什么意义呢?!是不是GC在那里为编码器照顾这个?

rsl*_*ite 15

正如其他人在这里所说GC是非确定性的,所以你不知道什么时候会收集你的对象.我要澄清的是,这不是内存的问题,而是系统资源(打开的文件,数据库连接),这些资源很昂贵,应该尽快发布.Dispose允许您在知道不再使用连接时执行此操作.如果它们没有及时发布,系统可能会耗尽这些资源,并且GC不知道这一点.这就是你必须手动完成的原因.

另外我想补充一点,使用'using'语句将以很好的方式为您完成.


dda*_*daa 7

垃圾收集在这里负责释放未使用的内存.

扩展GC以释放其他资源的原因有多种是有问题的.其中之一是终结器(在对象被垃圾收集时执行的方法)使得引用循环无法收集,除非您强烈限制从终结器中取消引用,这使得它们使用起来非常棘手.

另一个原因是大多数资源需要以某种及时的方式解除分配,这在依赖垃圾收集时是不可能的.

另一个原因是限制GC到内存管理涉及任何应用程序中的大量资源管理,以及几乎所有非有趣的资源管理.其他资源通常很有趣,值得一些额外的代码来明确它们的发布方式.

另一个原因是在某些应用程序中,GC使应用程序更快,因为它减少了为满足所有权语义而完成的复制量.这不是其他资源的问题.

其他人可以这样持续几个小时.


Mic*_*urr 6

但是如果你不得不担心手动处理东西,那么GC有什么意义呢?!是不是GC在那里为编码器照顾这个?

问题是你不知道的时候,GC将运行.如果你的应用程序从不压力记忆,它可能根本不会运行.

  • ......有些资源比记忆更为稀缺. (2认同)

pli*_*nth 5

假设我有这个代码:

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,我的MonkeyMonitor检查猴子,如果它们太粗暴,它会获得一个宝贵的系统资源 - 一只猴子抓住系统上的爪子,用它抓住一只猴子并打它.由于我没有丢弃它,猴爪仍然抓住悬挂在其余笼子上方的猴子.如果剩下的猴子继续变得粗暴,我不能制作新的MonkeyGrabber,因为它仍然有帮助.哎呀.一个人为的例子,但你明白了:实现IDisposable的对象可能会占用有限的资源,应该及时发布.GC最终可能会放弃.

此外,还需要及时发布一些资源.我有一组类,如果在应用程序退出之前它们没有被应用程序或GC处理,将导致应用程序崩溃,因为它们来自的非托管资源管理器已经在GC到达它时已经消失了.

更多关于IDisposable.

使用是你的朋友 - 这是迄今为止我们与RAII最接近的.