C# 垃圾回收总结
- 说老实话我还是觉得自己没太看懂,这里只是对看的稀里糊涂的东西做个简单的总结
- 有一个安代回收,可以减少每一次遍历的对象
- 有三种情况可能引起垃圾回收,分别是: (1) 垃圾回收的定时时间到 (2)可以使用的内存不能满足内存请求 (3)GC.Collect强制垃圾回收
- 垃圾回收器自动回收不再被引用的托管对象所占用的内存。垃圾回收器不识别非托管代码中对对象的引用。垃圾回收器只负责托管内存的分配,不维护有关一个对象所保持的资源的。
- GC.KeepAlive方法提供一种机制,该机制可防止垃圾回收器回收在非托管代码中仍使用的对象。
- 某个类型使用的非托管资源在回收该类型的实例之前必须释放时,该类型可以实现终结器。
- 多数情况下,如果某对象有终结器,则垃圾回收器会在释放该对象前调用其终结器。有些情况下不调用,比如终结器被GC.SuppressFinalize 的调用软禁止掉了
- 多数情况下,终结器通过重写 Object.Finalize 方法来实现,但是,无法在 C# 或 C++ 编程语言中重写 Finalize 方法。在 C# 中可使用析构函数语法实现 Finalize 方法,编译器将析构函数转换为对 Object.Finalize的重写。
- 终结器的工作有两个步骤:(1) 释放非托管资源 (2) 释放不再引用的对象所占用的内存
- 在资源必须在特定时间释放的方案中,类可以实现 IDisposable 接口。 Dispose 方法的实现可以调用 GC类中的方法来自定义垃圾回收器的完成行为。
- 通过将对象的范围限制为 protected,您可以防止应用程序用户直接调用对象的 Finalize 方法。
public void Dispose() {
Dispose(true);
//如果调用了Dispose(),就不需要再调用终结器了
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
// 检查是不是已经进行过垃圾回收
if(!this.disposed)
{
// 如果正在进行垃圾回收
if(disposing)
{
// 回收托管资源
//TODO:
Components.Dispose();
}
// 不论什么情况下,都会回收非托管资源
CloseHandle(handle);
handle = IntPtr.Zero;
// 如果与线程安全性需要,disposing的值由客户端按照需要来设置
}
disposed = true;
}
~BaseResource()
{
// 终结器只需要释放非托管资源
Dispose(false);
}