The*_*son 3 c# garbage-collection
我可以在同一个类中实现这两个方法吗?
public class MyClass : IDisposable
{
// some implementation
// if i missed to call Dispose() method;
~MyClass()
{
// it means, clear all does not mananage resources
// but dont use Dispose() method
}
public void Dispose()
{
// clear resources
// if i call this method will i can do this:
GC.SuppressFinalize()
// it means dont use Finalizw method for this object
}
}
Run Code Online (Sandbox Code Playgroud)
我对吗?因为我无法理解这个GC.SuppressFinalize()方法?
是的,您可以按照自己的意愿实施这两种方法.
通常,如果对象可以同时具有托管和非托管引用,则正确的模式是:
public class MyClass : IDisposable
{
~MyClass()
{
Dispose(false);
}
public void Dispose()
{
GC.SuppressFinalize(this);
Dispose(true);
}
public virtual void Dispose(bool disposing)
{
if(disposing)
{
// clear MANAGED references
}
// free UNMANAGED resources
}
}
Run Code Online (Sandbox Code Playgroud)
但您可以根据需要实现此功能.这只是一种模式.例如,如果您没有任何非托管资源并且您的类是密封的(因此您可以确定它不会使用任何非托管资源),您可以实现它,就像:
public sealed class MyClass : IDisposable
{
public void Dispose()
{
// release managed references
}
}
Run Code Online (Sandbox Code Playgroud)
忘记终结者了.
在第一个模式中,GC.SuppresFinalize(this)正在做的是告诉垃圾收集器~MyClass()在释放对象时不应该调用终结器(方法):如果你已经专门调用Dispose()那么你已经调用了你的虚 Dispose(bool)函数,那么为什么要再次调用呢?
问题是终结器本身在C#中是不确定的:你不知道什么时候会被调用...你甚至不能保证它甚至会被调用(尽管它会在正常清理过程中被调用)如果之前没有被调用过,那就是为什么IDisposable存在,它是一种确定性地释放托管对象的方式,释放并释放由它分配的非托管资源.
如果GC释放了一个对象,那么它所拥有的所有托管引用也将被释放,因此在调用终结器时不需要清除托管引用.
但是,您的应用程序应尽最大努力释放和释放它拥有的任何非托管资源.
如果你忘了Dispose(),它们应该有最后一次机会被释放(当GC收集对象时,或者在应用程序运行时进行最后的清理).在正常模式中你也可以实现一个终结器,如果你之前还没有完成它,请告诉它清理非托管资源
请注意,与流行的看法相反,呼叫Dispose()并不特别,它只是一个方法调用:你可以调用它FreeMyObject()或者FooBar()如果你想要的话.它不会使垃圾收集器释放任何内存.有一个模式通过使用IDisposable,非常重要,它获得自己的语言语法构造(using块),但它只是一个模式.你可以做同样Dispose()没有实施IDisposable的事情.