重新创建对“this”的根引用是否合法? 在 .net 析构函数中?

发布于 2024-07-14 14:42:49 字数 551 浏览 7 评论 0原文

在 .net 中编写以下内容合法吗?

   public class A
    {
        public int i = 0;
        ~A()
        {
            Aref = this;
        }
    }


    public static A Aref;
    static void Main(string[] args)
    {
        Aref = new A();
        int gen = GC.GetGeneration(Aref);
        Aref = null;
        GC.Collect(gen, GCCollectionMode.Forced);
        GC.WaitForPendingFinalizers();
        Console.WriteLine(Aref.i);
        Console.ReadLine();
    }

它可以正常工作并按预期将“0”写入控制台,但我想知道它是否保证始终有效。

有人知道幕后发生了什么吗?

Is it legal to write the following in .net ?

   public class A
    {
        public int i = 0;
        ~A()
        {
            Aref = this;
        }
    }


    public static A Aref;
    static void Main(string[] args)
    {
        Aref = new A();
        int gen = GC.GetGeneration(Aref);
        Aref = null;
        GC.Collect(gen, GCCollectionMode.Forced);
        GC.WaitForPendingFinalizers();
        Console.WriteLine(Aref.i);
        Console.ReadLine();
    }

It works and writes '0' to the console as expected, but I'm wondering if it's guaranteed to always work.

Does someone know what's happening behind the scene?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

乖乖兔^ω^ 2024-07-21 14:42:49

这就是所谓的复活,而且是合法的。 谷歌搜索“.net 对象复活”(以及类似的术语),您会发现类似以下内容:

复活和 .NET 垃圾收集器

物体复活

只要确保这些僵尸物体不会回来并试图吃掉你的大脑或其他东西即可。 就像所有的死灵术一样,这是危险的东西。 (主要是因为类层次结构中较高层的终结器可以释放一些必要的资源。另请注意,如果对象“未引用”,终结器将不会再次运行,除非您调用 GC.ReRegisterForFinalize代码>.)

It's called resurrection, and it's legal. Google for ".net object resurrection" (and terms like it) and you'll find stuff like:

Resurrection and the .NET Garbage collector

Object Resurrection

Just make sure these zombie objects don't come back and try to eat your brain or something. Like all necromancy, this is dangerous stuff. (Mostly because the finalizers higher up in the class hierarchy can have released some essential resource. Also note that the finalizer won't be run a second time if the object gets "unreferenced", unless you call GC.ReRegisterForFinalize.)

苍风燃霜 2024-07-21 14:42:49

它之所以有效,是因为第一次垃圾收集不会收集实例。 它只是安排实例运行其终结器。 然后,终结器为该实例创建一个新的根,因此当下一次收集发生时,该实例实际上已建立根,因此无法进行收集。

你应该非常小心这个困难。 如果使用终结器来确保对象被释放,这实际上违反了协议,因为一次性模式规定,如果在释放后使用已释放的实例,则应抛出 ObjectDisposeException。

It works because the first garbage collection doesn't collect the instance. It just schedules the instance to have its finalizer run. The finalizer then creates a new root to the instance, so when the next collection happens the instance is actually rooted and thus not up for collection.

You should be very careful with this tough. If the finalizer is used to make sure an object is disposed, this actually violates the protocol because the disposable patterns says that a disposed instance should throw an ObjectDisposedException if it is used after being disposed.

放低过去 2024-07-21 14:42:49

垃圾收集器将对象分为三组:

  1. 仍然存活的对象,因为最后检查终结队列之外是否存在根引用;
  2. 那些需要删除的,因为任何地方都不存在根引用;
  3. 那些需要最终确定的,因为根引用存在于最终确定队列中,但没有其他地方。

Objects cannot be deleted unless there's no rooted reference anywhere. Finalization is a distinct stage before deletion; note that while an object is registered for finalization, all objects it references directly or indirectly will be protected from deletion, but not from finalization.

The garbage collector divides objects into three groups:

  1. Those which are still alive, because at last check a rooted reference existed outside the finalization queue;
  2. Those which need to be deleted, because no rooted reference exists anywhere;
  3. Those which need to be finalized, because a rooted reference exists in the finalization queue, but nowhere else.

Objects cannot be deleted unless there's no rooted reference anywhere. Finalization is a distinct stage before deletion; note that while an object is registered for finalization, all objects it references directly or indirectly will be protected from deletion, but not from finalization.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文