Что будет с объектами, которые называются GC.SuppressFinalize? Я понимаю, что это означает, что GC не будет вызывать финализатор таких объектов (деструктор), если так, когда эти объекты действительно будут разрушены? в противном случае произойдет утечка памяти, верно?
Вы неправильно понимаете, для чего нужна финализация. Финализация предназначена для очистки ресурсов, которые не управляемой памяти.
Предположим, у вас есть объект ссылочного типа, который содержит целочисленное поле. Это целочисленное поле просто является дескриптором файла, который был получен путем вызова неуправляемого кода для открытия файла.
Поскольку какая-то другая программа может захотеть получить доступ к этому файлу, вежливо закрыть файл как можно скорее. Но среда выполнения .NET не знает, что это целое число имеет какое-то особое значение для операционной системы. Это просто целое число.
Способ решения этой проблемы обычно заключается в том, что вы помечаете объект как реализующий IDisposable, а затем вызываете «Dispose» для объекта, как только закончите с ним. Ваша реализация «Утилизация» затем закрывает файл.
Обратите внимание, что здесь ничего особенного не происходит. Это просто соглашение, что метод, который очищает неуправляемый ресурс, называется «Уничтожить», а объект, который должен быть удален, реализует IDisposable. Сборщик мусора абсолютно ничего не знает об этом.
Так что теперь возникает проблема: что если кто-то забудет позвонить в Dispose? Файл остается открытым навсегда ? (Очевидно, что файл будет закрыт после завершения процесса, но что, если процесс будет выполняться в течение длительного времени?)
Для решения этой проблемы вы используете финализатор. Как это работает?
Когда объект собирается собирать мусор, сборщик мусора проверяет его на наличие финализатора. Если это так, то вместо сбора мусора он помещает его в очередь финализатора. В какой-то неопределенный момент в будущем запускается поток, который проверяет очередь и вызывает специальный метод «Завершить» для каждого объекта. После этого объект удаляется из очереди финализации и помечается как «эй, я уже финализирован». Теперь объект снова пригоден для сбора, поэтому сборщик мусора в конечном итоге запускается и собирает объект без , помещая его в очередь завершения.
Очевидно, что «Завершить» и «Распоряжаться» часто нужно делать одно и то же.
Но теперь возникает другая проблема. Предположим, вы располагаете объектом. Теперь его не нужно завершать. Завершение стоит дорого; он сохраняет мертвый объект живым гораздо дольше, чем нужно. Поэтому традиционно, когда кто-то удаляет объект, реализация Dispose не только закрывает неуправляемый ресурс, но и отмечает объект как «этот объект уже завершен, не завершайте его снова». Таким образом, он обманывает сборщика мусора, заставляя его не помещать объект в очередь завершения.
Итак, давайте ответим на ваши конкретные вопросы:
Что будет с объектами, которые называются GC.SuppressFinalize?
Когда объект мертв, сборщик мусора просто восстановит память объекта, не помещая объект в очередь финализатора.
Я понимаю, что это означает, что GC не будет вызывать финализатор таких объектов
GC никогда не вызывает финализатор. Финализатор потока является единственным, что вызывает финализаторы.
когда эти объекты действительно будут разрушены?
Непонятно, что вы подразумеваете под "разрушенным".Если вы имеете в виду "когда будут работать финализаторы?"ответ "никогда", потому что вы сказали, чтобы подавить завершение.Если вы имеете в виду «когда память в управляемой куче будет восстановлена?», Ответ будет «как только объект будет определен как мертвый сборщиком мусора».Это произойдет на раньше , чем обычно, потому что объект не будет поддерживаться в очереди финализатора.