垃圾回收不起作用 int .net c#

garbage collection not working int .net c#

提问人:ILovePizza 提问时间:1/12/2022 最后编辑:Good Night Nerd PrideILovePizza 更新时间:1/12/2022 访问量:642

问:

我正在以以下代码为例:

var p = new person("Amir");
var zp = new person("Amiraa");
GC.Collect();
GC.WaitForPendingFinalizers();

class person
{
    public person(string nName)
    {
        Console.WriteLine("New");
        string name = nName;
    }

    ~person()
    {
        Console.WriteLine("Garbage collected");
    }
}

但是控制台上的资源只显示“新”,而不是“垃圾收集”。那么为什么GC不工作呢?

C# .NET 垃圾回收

评论

0赞 Damien_The_Unbeliever 1/12/2022
请记住,a) 垃圾回收在 .NET 中确实有效,b) 它旨在让您不必考虑何时收集对象
0赞 Federico Alterio 1/13/2022
c# 中的析构函数是非常不确定的。请看埃里克·利珀特(Eric Lippert)的回答:stackoverflow.com/questions/44573392/......

答:

6赞 canton7 1/12/2022 #1

试一试,你会注意到你的代码在 Release 中按预期工作,但不一定是 Debug

这是因为变量 和 在调用 时仍在范围内。它们仍然引用实例。pzpGC.Collect()person

在 Release 中,GC 将愉快地收集变量引用的对象,这些对象仍在范围内,只要它们不再被使用。在调试中,调试器需要允许你查看范围内所有变量的内容,因此 GC 无法收集它们。

如果这样做:

var p = new person("Amir");
var zp = new person("Amiraa");

p = null;
zp = null;

GC.Collect();
GC.WaitForPendingFinalizers();

你将看到预期的输出,即使在调试中也是如此。请注意,.NET 6 中引入的分层编译会影响这一点,并且上述测试可能无法按预期工作。

如果引入单独的方法,则 和 的生存期是显式作用域的,则即使在 .NET 6 的调试中,也应看到预期的行为:pzp

Test();
GC.Collect();
GC.WaitForPendingFinalizers();

void Test()
{
    var p = new person("Amir");
    var zp = new person("Amiraa");
}

评论

0赞 ILovePizza 1/12/2022
嘿,是的,我想过了 - 但它仍然不起作用,我没有得到 GB。(控制台仍然只显示新的)。
0赞 canton7 1/12/2022
请参阅我的答案中的链接 - 它们显示了我描述的输出。如果你看到不同的东西,那么恐怕我无法重现它。确保您可以重现您在 sharplab.iodotnetfiddle.net 等网站上看到的内容
0赞 ILovePizza 1/12/2022
您发送的链接也只会将“new”写入控制台。它不显示 ~(person) 的输出
0赞 canton7 1/12/2022
请参阅“发布”链接。有趣的是,输出似乎发生了变化......p = null
0赞 ILovePizza 1/12/2022
是的,我明白你的意思。但由于某种原因,它没有显示在 .vs 2022 上