加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 垃圾收集器是否隐式使用析构函数方法,并配置开发人员用于

发布时间:2020-12-16 01:50:20 所属栏目:百科 来源:网络整理
导读:我可以看到已经有很多关于dispose与析构函数方法的线程,但我只是想确保在继续之前我正确理解它们. 垃圾收集器是否隐式使用析构函数方法,以便何时不再引用对象(即不再需要),并配置开发人员使用的方法来显式处理垃圾收集器可能无法处理的对象? 此外 – 我现在
我可以看到已经有很多关于dispose与析构函数方法的线程,但我只是想确保在继续之前我正确理解它们.

垃圾收集器是否隐式使用析构函数方法,以便何时不再引用对象(即不再需要),并配置开发人员使用的方法来显式处理垃圾收集器可能无法处理的对象?

此外 – 我现在正在阅读所有这些,似乎这是一个用这些方法的情况.例如,给出以下代码:

class DansClass : IDisposable
{
    public void Dispose()
    {
        GC.SuppressFinalize(this);
        Console.WriteLine("Disposing...");
    }

    -DansClass()
    {
        Console.WriteLine("Destructing...");
    }
}

输出将是:

解构…

可以理解,因为我们已经抑制了finalize(析构函数)所以我们只看到Dispose输出.

但是,如果我注释掉SuppressFinalize()方法,则输出为:

处置……

为什么析构函数不被称为?

解决方法

处理方法,终结器和C#讽刺命名的析构函数是存在的,因为许多对象要求其他实体代表他们做事,直到另行通知(通常授予对文件,内存区域,通信流,硬件设备等的独占使用) GDI处理等);如果发出此类请求的对象在没有其他实体知道不再需要其服务的情况下消失,则代表被放弃对象留出的任何内容将无法无法访问.

IDisposable.Dispose方法提供了一种很好的一致方式来告诉对象它将不再被要求做任何需要其他实体帮助的事情,并且任何其他代表它做任何事情的实体应该被告知停止做所以.如果正确调用IDisposable.Dispose,则对象可以最小化外部实体代表他们行动的程度.

不幸的是,由于各种原因(大多数是容易避免的;有些不是),有时会抛弃对象而没有IDisposable.Dispose已被调用.这将导致外部实体必须至少在一段时间内代表被抛弃的对象无用地继续行动.为了避免外部实体代表外部实体永远行动,系统可以通知对象他们已经被放弃,从而使他们有机会向外部实体通知这一事实.每当创建一个类重写Object.Finalize的对象时,它将被放置在一个特殊的对象列表中,如果它们被放弃,它们将被通知.此列表上的存在本身并不足以使对象被视为“活动”,但在垃圾收集器从内存中删除死对象之前,它将检查它们是否在destroy-before-destruction列表中.列表中的所有死对象将从请求通知的对象列表中移动,如果/何时它们被放弃到需要通知它们已被放弃的对象列表.在第二个列表上的放置将导致死对象以及它们持有引用的任何对象再次被视为“活动”,至少在通知已执行之前.但是,当它们被移动到第二个列表时,它们将从第一个列表中删除,这样如果以后发现它们再次死亡,它们将被记忆清除而不另行通知.

垃圾收集完成后,如果任何对象在需要通知放弃的对象列表中,系统将调用每个此类对象的Object.Finalize方法.通常,一旦在这样的对象上调用了Object.Finalize,就不再有对它的rooted引用了,它将在下一个垃圾收集时消失.但是,物体可能会复活.

在vb.net中,据我所知,大多数.net语言,只需通过以通常的方式声明覆盖来覆盖Object.Finalize.无论出于何种原因,C#的创造者决定禁止这样做.相反,在C#中,必须使用一种语言结构,具有讽刺意味地称为“析构函数”,以覆盖Finalize,以便发现被放弃的对象不会在没有通知的情况下被销毁,而是有机会进行清理.

在Object.Finalize的实际操作中有许多棘手的皱纹,除非绝对必要,否则最好避免依赖它.具有讽刺意味的“破坏者”实际上并没有破坏物体,而是推迟了它们的破坏.在对象上调用GC.SuppressFinalize()会将它从请求通知的对象列表中删除;如果在一个对象上调用Dispose,并且它反过来调用GC.SuppressFinalize()作为它的最后一个操作,那么让一个对象覆盖Finalize或声明一个“析构函数”没有任何特别的伤害,但一般来说最好是仅在相对简单的类中覆盖Finalize(或声明“析构函数”).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读