我打电话的时候object.Dispose(); CLR会立即从内存中销毁对象,还是在下一个循环中标记要删除的对象?
我们GC.SuppressFinalize()在Dispose()之后立即调用,这是否意味着,"不要再次收集对象以进行处置,因为它已经提交给了移位".
实际上哪一代负责破坏,我猜第2代.
ang*_*son 11
首先,IDisposable.Dispose和GC不是一回事.
GC将清理内存使用情况,IDisposable.Dispose用于确定性地释放资源,如文件句柄,数据库连接,网络连接等.
让我们先解决最终问题.
如果一个对象声明了一个终结器,那么当GC出现以将其从内存中释放时,该对象将被特别处理.该对象不是一次被释放,而是放在一个单独的列表中.
在后台,终结线程正在运行此列表并调用此列表中对象的终结器方法.调用终结器方法后,将从列表中删除该对象.
这里的要点是,虽然对象在此列表中,但它不符合收集条件.这意味着具有终结器的对象一旦符合收集条件,将暂时转换为不再符合收集条件但尚未完成的状态.再次发现对象后,在终结器运行并从该列表中删除后,它将从内存中释放.
GC.SuppressFinalize 只是一个对象说"终结器不再需要运行,如果你发现这个对象有资格收集,只需立即释放它"的方法.
IDisposable.Dispose另一方面,一旦由对象实现,则与垃圾收集器不完全相关.GC系统中没有任何内置功能可以确保Dispose调用该方法.这意味着具有Dispose方法的对象可以在不Dispose被调用的情况下轻松释放.
此外,调用Dispose不会以任何方式使对象符合收集条件.使对象符合收集条件的唯一方法是删除对它的所有强引用,通常是让局部变量超出范围(方法返回)或从其他对象(如列表,事件处理程序,等等.)
如果要调用它,那么"链接"就是内部具有此类资源的对象通常会实现终结器(如果资源是非托管的).如果资源是受管理的资源(如FileStream对象),则该对象将根据需要自行完成最终确定.但是,如果您要保留非托管资源,例如通过P/Invoke检索的文件句柄,那么您应该实现终结器.
通常情况下,终结器和IDisposable.Dispose该对象都将清理该资源,然后通常Dispose称其GC.SuppressFinalize为"我已经处理过它,如果有资格进行收集,您可以释放该对象".
但是,如果您只是调用Dispose,但仍保留对该对象的引用(事件处理程序,静态字段,局部变量等),则该对象尚不符合收集条件且不会被释放.
所以,总结一下:
Dispose通常进行调用以释放资源(非托管或托管).它不以任何方式影响GC是否可以收集对象,或将于何时完成.奖金问题:
如果出现以下情况,您认为会怎样?
希望这能回答你的问题,如果没有,请发表评论或澄清你的问题,我会编辑我的答案.
| 归档时间: |
|
| 查看次数: |
725 次 |
| 最近记录: |