弱引用不被垃圾收集

问题描述 投票:0回答:1

我的理解是,在对

Target
WeakReference
的所有强引用都设置为 null 并调用 GC 后,该弱引用不应该再存在。

然而,下面的代码似乎并没有遵循这个期望:

    static void Main(string[] _) {
        var person = new Person();
        var wr = new WeakReference(person);

        person = null;

        // We should have access to the person here
        if (wr.Target is Person shouldExist)
        {
            Console.WriteLine($"Person exists! IsAlive: {wr.IsAlive}.");
            shouldExist = null;
        }
        else
        {
            Console.WriteLine($"Person does not exist :( IsAlive: {wr.IsAlive}.");
        }

        // Invoke GC.Collect.            
        GC.Collect();


        if (wr.Target is Person shouldNotExist)
        {
            Console.WriteLine("This person should have been garbage collected");
            Console.WriteLine($"IsAlive: {wr.IsAlive}");
        }
        else
        {
            Console.WriteLine("This person was garbage collected and weak reference is no longer alive");
            Console.WriteLine($"IsAlive: {wr.IsAlive}");
        }
    }

哪里

class Person
{
    private int mI = 3;
    public int MI { get => mI; set => mI = value; }
}

输出是

人存在!还活着:是的。 此人应该被垃圾收集 还活着:真实

我期望的输出是:

人存在!还活着:是的。 此人已被垃圾回收,弱引用已不再存在 还活着:假

我是否遗漏了一些关于弱引用如何工作的内容?

c# weak-references
1个回答
0
投票

Person
中使用对
Main()
对象的引用可以使对象保持活动状态,直到方法结束。

如果您按如下方式更改代码(以便在单独的方法中访问

Person
对象),它将按预期工作:

public static class Program                                    
{
    static void Main()
    {
        var wr = getWeakReference();
        checkPersonExists(wr);
        GC.Collect();

        if (wr.Target is Person shouldNotExist)
        {
            Console.WriteLine("This person should have been garbage collected");
            Console.WriteLine($"IsAlive: {wr.IsAlive}");
        }
        else
        {
            Console.WriteLine("This person was garbage collected and weak reference is no longer alive");
            Console.WriteLine($"IsAlive: {wr.IsAlive}");
        }
    }

    static WeakReference getWeakReference()
    {
        var person = new Person();
        var wr     = new WeakReference(person);

        return wr;
    }

    static void checkPersonExists(WeakReference wr)
    {
        // We should have access to the person here
        if (wr.Target is Person)
        {
            Console.WriteLine($"Person exists! IsAlive: {wr.IsAlive}.");
        }
        else
        {
            Console.WriteLine($"Person does not exist :( IsAlive: {wr.IsAlive}.");
        }

    }
}

class Person
{
    private int mI = 3;
    public  int MI { get => mI; set => mI = value; }
}
© www.soinside.com 2019 - 2024. All rights reserved.