Amir228
@Amir228

Почему может не срабатывать финализатор при вызове GC.Collect?

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");


            Person person = new Person("Vitalya");
            person = null;
            
            GC.Collect(1, GCCollectionMode.Forced);//Почистить от мусора
            Console.Read();

            Console.WriteLine("Program complide.");
        }
    }

    public class Person : IDisposable
    {
        public string Name { get; init; }
        public Person(string name) =>
            Name = name;


        ~Person() => PersonDispose(false);
        public void Dispose() => PersonDispose(true);
        protected virtual void PersonDispose(bool suppressFinalize)
        {
            if (suppressFinalize)
                GC.SuppressFinalize(this);

            Console.WriteLine("delete");
        }
    }

Почему на консоль не выводиться "delete"? Dispose работает(если вызвать), а вот финализатор нет. Person ставлю на null, обьект без ссылок должен удаляться, может даже удаляеться но почему то метод не работает. Я помню что финализатор может и не выполнять свой код если появляеться ошибка, но ведь ее нету.
  • Вопрос задан
  • 107 просмотров
Решения вопроса 1
vabka
@vabka Куратор тега .NET
Токсичный шарпист
1. Финализация вполне может быть отложена по усмотрению сборщика мусора
2. JIT вполне может так скомпилировать твой код, что вот этот = null будет опущен => при поиске ссылок, ссылка всё ещё будет на стеке.
Попробуй вынести в новый метод и посмотреть там.

Ну и такой код как у тебя в реальном мире лучше не использовать (это я про принудительный вызов гц, логи в финализаторе, и финализатор который не чистит неуправляемые ресурсы)

PS: читаем внимательно документацию и особенно слова "не гарантирует"

Используйте параметр , mode чтобы указать, должна ли сборка мусора происходить немедленно или только при оптимальном времени для освобождения объектов. Использование этого метода не гарантирует, что вся недоступная память в указанном поколении будет освобождена.

Чтобы настроить навязчивость сборки мусора в критические периоды в приложении, задайте LatencyMode свойство .

Сборщик мусора не собирает объекты с номером поколения, превышающим указанное параметром generation . Используйте свойство , MaxGeneration чтобы определить максимально допустимое generationзначение .

Чтобы сборщик мусора учитывал все объекты независимо от их создания, используйте версию этого метода, которая не принимает параметров.

Чтобы сборщик мусора отнимает объекты до указанного поколения объектов, используйте перегрузку GC.Collect(Int32) метода . При указании максимального поколения собираются все объекты.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы