[英]If an object has been disposed, does suppressing the gc finalizer save it some time?
[英]When does CLR say that an object has a finalizer?
我知道在C#中,如果你编写~MyClass()
,这基本上转换为override System.Object.Finalize()
。 因此,无论您是否编写析构函数 ,CLR中的每个类型都将包含一个Finalize()
方法(至少是System.Object
)。
1]那么,这是否意味着,默认情况下,每个对象都有一个终结器?
2] CLR决定一个对象应该通过终结队列的基础是什么?
我问这个,因为,我有一个类,说ManagedResourceHolder
实现了IDisposable
,但没有在其IDisposable.Dispose()
方法中调用GC.SuppressFinalize(this)
。 该类没有任何非托管资源,并且不需要~ManagedResourceHolder()
方法,这反过来意味着不需要GC.SuppressFinalize(this)
调用,因为没有终结器 。
3]在上述场景的上下文中,在实现IDisposable时是否总是需要提供终结器? (即使在没有非托管资源的类上)
该FxCop的规则CA1816是给我一个违反了这一点,我得到的回应在这里 ,当我问在MSDN上的CA论坛搞糊涂了。
谢谢。
问题1和2 :CLR基本上检查终结器是否被覆盖。 如果不是,它会将其视为没有终结器。
在System.Object中使用终结器的好处是编译器知道他们总是可以调用base.Finalize()
。这可以避免版本控制问题。 考虑一个没有System.Object.Finalize()
的世界:
如果没有对象中的Finalize
方法,MyCompany.DerivedClass中的终结器不能调用任何东西。 当Acme.BaseClass的第2版带有终结器时会导致问题。 除非您重新编译MyCompany.DerivedClass,否则DerivedClass的实例将在不调用BaseClass.Finalize的情况下完成,这显然是一件坏事。
现在考虑与 System.Object.Finalize相同的情况 - 编译器在DerivedClass.Finalize中自动插入对base.Finalize的调用,在版本1中只调用System.Object中的no-op实现。 当Acme.BaseClass的第2版出来时,对base.Finalize
的调用将(无需重新编译DerivedClass)调用BaseClass.Finalize。
问题3 :不,您不需要因为实现IDisposable而拥有终结器。 终结器应仅用于非托管资源, 其他任何东西都不会被清理 - 即您可以直接引用的资源。 例如,假设您有一个具有FileStream
成员变量的类。 您希望实现IDisposable
以便您可以尽快关闭流,如果调用者记得 - 但如果他们不记得调用Dispose()
,则该流将有资格与您的对象同时进行垃圾回收。 相信FileStream
有一个合适的终结器(或者使用终结器等对其他东西的引用),而不是试图在你自己的终结器中清理它。
从.NET 2.0开始,使用SafeHandle类,您需要自己的终结器应该是非常罕见的。
1:它只是被重写(在有用的意义上)
2:由1定义,并且没有调用GC.SuppressFinalize(加上重新注册等)
3:当然不是; 实际上,除非您直接处理非托管资源,否则您不应该使用终结器。 你不应该仅因为它是IDisposable而添加终结器 - 但是具有终结器的东西通常也应该是IDisposable。
Finalize()
才会被CLR计算。 更新:每个班级都负责管理自己的资源。 由于面向对象范例的抽象和封装特性,类的消费者不应该间接关注它拥有的资源。 因此,您应该手动释放您拥有的资源(您拥有的是您在将其他东西视为黑盒时 直接拥有的资源)或将其留给GC以释放它们。 对于非托管资源,您无法将其保留到GC,因此必须手动释放它。 从这个意义上讲,Jon提到的SafeHandle是非托管资源的托管抽象 ,因此它应被视为有价值的托管资源(这是一个黑盒子,用于管理非托管资源本身的最终化)。
1)是(凭借继承)
2)没有任何东西持有对类实例的引用(这将使其有资格完成)
3)是(为什么一个人应该实现IDisposable,除非它要求用户明确地调用dispose?.net中的连接类使用一个非管理资源并且如果你不调用dispose,它将依赖它。由于GC时间未知,连接将保持打开,直到那个时间)
这是我的理解。
我错了。 在这种情况下,专家会为我纠正问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.