垃圾回收应该已删除对象,但WeakReference.IsAlive仍然返回true对象、垃圾、WeakReference、IsAlive

2023-09-02 01:58:58 作者:何必执着一张脸

我有一个测试,我有望通过,但垃圾收集器的行为是不是因为我presumed:

I have a test that I expected to pass but the behavior of the Garbage Collector is not as I presumed:

[Test]
public void WeakReferenceTest2()
{
    var obj = new object();
    var wRef = new WeakReference(obj);

    wRef.IsAlive.Should().BeTrue(); //passes

    GC.Collect();

    wRef.IsAlive.Should().BeTrue(); //passes

    obj = null;

    GC.Collect();

    wRef.IsAlive.Should().BeFalse(); //fails
}

在这个例子中, OBJ 对象应GC'd,因此我预计 WeakReference.IsAlive 属性返回

In this example the obj object should be GC'd and therefore I would expect the WeakReference.IsAlive property to return false.

看来,因为 OBJ 变量是在同一范围内的 GC.Collect的它不是声明收集。如果我将OBJ声明和初始化测试通过的方法之外。

It seems that because the obj variable was declared in the same scope as the GC.Collect it is not being collected. If I move the obj declaration and initialization outside of the method the test passes.

没有人有任何的技术参考文档或解释这种现象?

Does anyone have any technical reference documentation or explanation for this behavior?

推荐答案

难道说的。应()扩展方法,以某种方式挂到一个参考?或许测试框架的一些其他方面引起此问题。

Could it be that the .Should() extension method is somehow hanging on to a reference? Or perhaps some other aspect of the test framework is causing this issue.

(我张贴此作为一个答案,否则我不能轻易地张贴code!)

(I'm posting this as an answer otherwise I can't easily post the code!)

我曾尝试以下code,它工作正常(的Visual Studio 2012,.NET 4的构建,调试和发布,32位和64位,在Windows 7上,四核处理器上运行):

I have tried the following code, and it works as expected (Visual Studio 2012, .Net 4 build, debug and release, 32 bit and 64 bit, running on Windows 7, quad core processor):

using System;

namespace Demo
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            var obj = new object();
            var wRef = new WeakReference(obj);

            GC.Collect();
            obj = null;
            GC.Collect();

            Console.WriteLine(wRef.IsAlive); // Prints false.
            Console.ReadKey();
        }
    }
}

当你试试这个code会发生什么事?

What happens when you try this code?