• 什么时候应该调用 GC.SuppressFinalize()?
  • 发布于 2个月前
  • 495 热度
    0 评论
  • 北风吹
  • 0 粉丝 66 篇博客
  •   
问题:
在 .NET 中,请问哪一种情况必须要使用 GC.SuppressFinalize() 方法,它到底能给到我什么好处?
解决方案:
SuppressFinalize() 方法只能被含有终结器方法的类使用,它通知 GC 这个 this 对象已经被手工清理了。
建议在 含有 finalizer 方法的类上使用 IDisposable 模式,参考如下代码:
public class MyClass : IDisposable
{
    private bool disposed = false;

    protected virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
                // called via myClass.Dispose(). 
                // OK to use any private object references
            }
            // Release unmanaged resources.
            // Set large fields to null.                
            disposed = true;
        }
    }

    public void Dispose() // Implement IDisposable
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    ~MyClass() // the finalizer
    {
        Dispose(false);
    }
}
通常来说,如果一个含有 finalizer 方法的类被创建,那么 CLR 就会一直密切监控着它,所以它的创建相比普通的类要更加昂贵一些,而 SuppressFinalize 方法就是告诉GC,我已经清除完毕了,你不需要从 FinalizeQueue 中去提取,这就有点像 C++ 的析构函数,但本质上不是一个东西。
总结:
其实很好理解,当创建了一个带有 finalizer 方法的类,那这个类的实例地址也会在 FinalizeQueue 中存放一份,当 GC 回收该对象时,GC会将其放到 FreachableQueue 队列中,这样终结器线程就能够从这个队列中提取,进而执行对象的 finalizer 方法,可以参考下面的代码:
namespace ConsoleApp5
{
    class Program
    {
        static void Main(string[] args)
        {
            Run();
            GC.Collect();
            Console.ReadLine();
        }

        static void Run()
        {
            var person = new Person();
            Console.WriteLine("person 已实例化!");
        }
    }

    class Person
    {
        ~Person()
        {
            Console.WriteLine("我是析构函数!");
            Console.ReadLine();
        }
    }
}

接下来问题来了,我能不能不要让 终结器线程 来执行我的析构函数呢?这就需要用 SuppressFinalize() 方法来抑制了,修改 Run 方法如下:
        static void Run()
        {
            var person = new Person();
            Console.WriteLine("person 已实例化!");

            GC.SuppressFinalize(person);
        }

可以看到,这回 终结器线程 没有执行我的析构函数了,就这么简单,如果有朋友对细节感兴趣,有机会用 windbg 让大家眼见为实。
用户评论