You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何C#中已置null并调用GC.Collect(),Starter对象仍未被GC回收?

原因解释

问题的核心在于后台任务的Lambda表达式隐式捕获了Starter实例的引用,具体细节如下:

  • 你在Start方法里的Task.Run中使用了成员变量a,C#里访问实例成员本质是this.a,编译器会自动让这个Lambda表达式持有当前Starter对象(this)的引用。
  • 后台Task处于持续运行的状态,它的执行上下文会持有这个Lambda委托的引用,而Lambda又握着Starter实例的引用——GC判断对象是否可回收的依据是是否存在有效引用链,所以这个Starter实例会被判定为"仍在被使用",不会被回收。
  • 你把变量s赋值为null,只是切断了Main方法里对Starter实例的引用,但后台任务的Lambda还攥着实例的引用,所以实例无法被GC回收,后台的循环自然会一直跑下去。

如果想验证这个逻辑,可以修改Lambda里的代码,比如去掉对a的引用,改成一个不访问实例成员的空循环:

Task.Run(() =>
{
    while (true)
    {
        Console.WriteLine("循环运行中");
        Thread.Sleep(1000);
    }
});

这时候再运行代码,Starter实例就会被GC回收,因为Lambda没有捕获this引用了。

内容的提问来源于stack exchange,提问作者Cavid Haciyev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 21:17:03