WeakReference 只保留 1 代中的对象?

WeakReference only keep the object in 1 generation?

我正在尝试使用 Wea​​kReference class 但我没想到它不会在下一次垃圾回收中保留该对象。为什么?

我不知道这个class的实际使用知识。

在我将 myObject 设置为 null 后,代码强制执行另一次垃圾回收。

编辑:在else if行的末尾,myObject没有被释放,是不是因为编译器知道代码中仍然使用了WeakReference wr对象,所以垃圾回收没有回收它?

 class Program
{
    static void Main(string[] args)
    {
        MyObject myObject = new MyObject(25);
        WeakReference wr = new WeakReference(myObject);

        if (wr.IsAlive) Console.WriteLine("Alive");

        myObject = null;

        GC.Collect();
        if (wr.IsAlive) Console.WriteLine("Still alive");
        else if(!wr.IsAlive) Console.WriteLine("Dead");

        //
        //edit: added this 
        GC.Collect();
        if (wr.IsAlive) Console.WriteLine("Still alive");
        else if (!wr.IsAlive) Console.WriteLine("Dead");
        //edit end
        Console.ReadKey();
    }
}

class MyObject : IDisposable
{
    private bool disposed = false;
    private int id = 0;
    public MyObject(int id)
    {
        this.id = id;
    }
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected void Dispose(bool disposing)
    {
        Console.WriteLine("disposed {0}", id);
        if (!disposed)
        {
            if (disposing)
            {
                //free managed
            }
            //free unmanaged
            disposed = true;
        }
    }

    ~MyObject()
    {
        Dispose(false);
    }
}

On the end of else if line the myObject is not disposed, is it because the compiler knows that WeakReference wr object is still used in the code so that the garbage collection does not reclaim it?

不,这是因为您 运行 附加了调试器的应用程序。请阅读@Hans Passant 的回答 了解详情。

如果您在发布模式下构建应用程序并且 运行 它没有附加调试器,您应该看到 "Alive"、"Dead" 和 "Dead" 被打印到控制台.我愿意。

您还应该从 MyObject class 中删除终结器,因为您没有使用非托管资源。

为什么您的对象无法在第一次回收中存活下来的简短回答:有两种类型的弱引用:短引用和长引用。 short 立即被收集,而 long 仅在它们的终结器完成时才被收集——这是一个 long weak reference 应该有终结器,这对你的情况来说是正确的,但另一个强制性要求是它应该在构造时将 trackResurrection 参数设置为 true(默认为 false)。终结器无论如何都会在第二次收集期间执行,但是 trackResurrection 设置为 false 对象不会被跟踪并且它的引用被设置为 null (但是正式地它在终结之前是活动的但无法访问)。