|
|
1
15
我可能走了,但你好像对
|
|
|
2
16
在对象不再被任何对象引用之前,它不会被垃圾收集。诚然,在某些极端情况下,这可能比你想象的要早,但你很少需要担心这些。
值得注意的是
|
|
|
3
5
碰巧 Raymond Chen 刚刚写了一系列描述.NET垃圾收集方面的博客文章。 This post 最直接的关系到您的问题(对象何时被垃圾收集?). |
|
|
4
3
Dispose()与垃圾收集没有任何关系。它所做的只是允许确定性的资源释放,但是您必须显式地调用它。当调用Dispose()时,调用它的对象不会被垃圾收集。当所有对它的引用都消失时,它将有资格进行垃圾收集。 |
|
|
5
2
这里有许多很好的答案,但我也想指出,人们认为您需要IDisposable的原因是,一个GC实际上应该命名为memorycollector,甚至是managedmemorycollector。GC在收集非托管内存资源(如文件、db conn、事务、Windows句柄等)时并不特别聪明。 其中一个原因是,一个托管对象可能拥有一个非托管资源,该资源需要几Gigs的RAM,但是对于GC来说,它看起来像8个字节左右。 对于文件、db conn等,您通常希望尽快关闭它们,以释放非托管资源并避免锁定问题。 对于Windows句柄,我们有线程关联性需要考虑。当GC在专用线程中运行时,该线程始终是释放Windows句柄的错误线程。 因此,GC有助于避免泄漏托管内存和减少代码混乱,但仍应尽快释放非托管资源。 使用()语句是一种祝福。 ps.我经常实现IDisposable,即使我没有任何直接的非托管资源,但它的重要作用并不是通知实现IDisposable的所有成员变量,这些变量被调用了Dispose。 |
|
|
6
1
好的,先处理!=垃圾收集。您可以调用Dispose,而从不将其垃圾收集,因为“Disposed对象”仍然可以有对它的引用。Dispose方法用于在CG运行之前“整理”对象(关闭打开的DB连接或文件连接等)。
在此实例中,B.Dispose正在对A调用Dispose方法,因为B正在引用变量A中的对象。这两者都不是CGD,因为它们尚未超出范围。
这里所发生的是,您正在创建对象A并返回它,所以当您离开test1时,A很可能被调用方法中的另一个变量引用。这意味着即使您已经离开了方法,a仍然是根的(很可能),并且在调用方法完成之前不会被cg'd。
这里正在创建B并调用Dispose。这并不意味着它会被收集起来。一旦程序离开方法,b就超出了范围,这意味着下次调用GC时可以收集它。 |
|
|
7
0
值得注意的是,调用Dispose实际上可能什么也不做。它使对象有机会清理数据库连接和非托管资源等资源。如果有包含非托管资源(如数据库连接)的对象,则Dispose将告诉该对象是时候清除这些引用。 垃圾收集中的基本问题是,“可以到达这个对象吗?”只要栈中的对象上有对您的对象的引用(或者在对象层次结构中的某个地方有对该对象的引用),就不会对该对象进行垃圾收集。 例子: obja创建一个objb,它创建一个objc。在objb不再引用objb之前,或者在objb不再被obj a引用之前,或者在没有对象保留对obj a的引用之前,不会对obj c进行垃圾收集。 同样,要问的问题是,“这个对象当前是否可以被代码中的任何内容引用?” |