У меня такой код:

 public class A
    {
        ~A()
        {
            Console.WriteLine("destructor");
        }
    }

 public static A Aref;
 static void Main(string[] args)
    {
        Aref = new A();
        int gen = GC.GetGeneration(Aref);
        Aref = null;
        GC.Collect(gen, GCCollectionMode.Forced);
        Console.WriteLine("GC done");

    }

Я думал, что мой метод Finalizer будет вызван при моем вызове GC.Collect, но это не так.

Кто-нибудь может объяснить мне, почему?

2
Brann 3 Мар 2009 в 17:16

3 ответа

Лучший ответ

Финализаторы не вызываются до возврата GC.Collect(). Финализаторы запускаются в отдельном потоке - вы можете дождаться их, вызвав GC.WaitForPendingFinalizers().

13
Jon Skeet 3 Мар 2009 в 17:22

Финализатор не вызывается во время сбора в вашем примере, потому что он все еще внедряется финализируемой очередью. Однако он запланирован для завершения, что означает, что он будет собран во время следующей сборки мусора.

Если вы хотите убедиться, что собраны экземпляры типов с финализатором, вам нужно сделать две таких коллекции.

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

Но обычно не следует вызывать метод Collect() самостоятельно.

6
Brian Rasmussen 3 Мар 2009 в 17:22
Зачем нужен второй сбор?
 – 
Mark13426
11 Ноя 2016 в 21:31
Для сбора любых объектов, допущенных к использованию, запустив их финализаторы. Если у типа есть финализатор, экземпляры будут укореняться в очереди финализатора до тех пор, пока финализатор не будет запущен или не будет подавлен.
 – 
Brian Rasmussen
11 Ноя 2016 в 23:58

Даже если вы попросите сборщик мусора, нет уверенности, что этот конкретный объект будет уничтожен (поскольку он не может быть в собираемом генерации в тот момент).

-2
Fabian Vilers 3 Мар 2009 в 17:22
В этом простом примере OP гарантирует, что соответствующая генерация собрана. Поэтому, если перед явным вызовом Collect () нет коллекции, она должна работать должным образом.
 – 
Brian Rasmussen
3 Мар 2009 в 17:55