GC.Collect()不立即收集?

Ken*_*rey 4 c# garbage-collection destructor finalizer

在聊天的讨论过程中,我编写了这个控制台应用程序.

码:

using System;

class Program
{
    static void Main(string[] args)
    {
        CreateClass();
        Console.Write("Collecting... ");
        GC.Collect();
        Console.WriteLine("Done");
    }

    static void CreateClass()
    {
        SomeClass c = new SomeClass();
    }
}

class SomeClass
{
    ~SomeClass()
    {
        throw new Exception();
    }
}
Run Code Online (Sandbox Code Playgroud)

结果:

Collecting... Done

Unhandled Exception: System.Exception: Exception of type 'System.Exception' was
thrown.
   at SomeClass.Finalize()
Run Code Online (Sandbox Code Playgroud)

我本来以为应用程序 Done打印会崩溃.

我不太关心如何制作它.我的问题是,为什么不呢?

max*_*max 12

具有终结器的对象无法在单个垃圾收集过程中收集.这些对象被移动到f-reachable队列中,并保持在那里直到调用终结器.只有在那之后它们才能被垃圾收集.

以下代码更好,但您不应该依赖它:

GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
Run Code Online (Sandbox Code Playgroud)

此外,即使出于测试目的,在终结器中抛出异常似乎对我来说太残酷了.

此外,终结器的有趣副作用:具有终结器的对象仍然可以"自我复活"(有效地防止自身的垃圾收集),如果this在终结器中存储引用(将其分配给某个静态变量).


Ed *_* S. 6

你看过文件了吗?

使用此方法尝试回收所有无法访问的内存.

它不是一个命令,它是一个请求,可能会或可能不会按您的意愿运行.无论如何,这通常不是一个好主意(有时很多很小的短期对象是由于某些过程而产生的,在这种情况下调用可能是有益的GC.Collect,但这种情况很少见).

因为看起来你似乎没有尝试解决一个真正的问题,而是用GC来解决这个问题,这是我提供的最佳建议.