2016-12-27 5 views
1

Я читаю книгу Джеффри Рихтера «CLR через C#». Это цитата оттуда:Почему сборщик мусора обрабатывает завершаемые объекты отдельно?

методы Finalize называются по завершении сборки мусора на объектах, что GC определила как мусор. Это означает, что память для этих объектов не может быть немедленно восстановлена ​​ , потому что метод Finalize может выполнять код, который обращается к полю. Поскольку финализируемый объект должен выжить сбор, он продвинут к другому поколению, заставляя объект жить гораздо дольше, чем это необходимо

Он ввел в заблуждении меня немного. Почему не может быть исправлен окончательный объект? Я не могу понять аргумент, что метод finalize может выполнять код, который обращается к полю. Что проблема? Более того, я не могу понять, почему конечный объект должен быть перенесен в старшее поколение и храниться в отдельной очереди (для обработки в другом потоке финализатора).

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

ответ

3

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

  1. Поскольку Finalize() просто нормальный метод объекта, поэтому код, в нем может получить доступ к любым полям объекта.

  2. Когда происходит сбор мусора, все потоки заморожены.

двумя точками сложить вместе с тем, что когда дс происходит, он не может выполнить метод Finalize() сразу (Все потоки приостанавливаются во дс !!), в то время как Finalize, как ожидается, будет вызываться до объекта собирается.

Все это приводит к тому, что сбор мусора не может убить объект непосредственно перед его вызовом метода Finalize(). Так дс берет объект из «списка смерти» (объект теперь называется воскрешены), и поставить его в очередь под названием «Freachable» («F„означает завершения,“достижимы» означает, что все объекты в нем не могут быть собраны в мусор, поскольку gc только собирает объекты недоступен из корней).

После завершения работы gc специальный выделенный поток с высоким приоритетом выведет каждую запись из очереди «Freachable» и вызовет на ней метод Finalize(), что делает этот объект окончательно «сборкой мусора», но, разумеется, первый gc уже закончился до этого процесса вызова Finalize(), все объекты, выгруженные из «Freachable», теперь могут быть запланированы только для следующей сборки мусора.

Кроме того, я не могу понять, почему конечный объект должен быть перенесен в старшее поколение и храниться в отдельной очереди (для обработки в другом потоке финализатора).

Чтобы это понять, вам необходимо сначала знать концепцию generation gc model. После того, как объекты вышли из очереди «Freachable» и снова готовы к сборке мусора, они были перенесены в более старшее поколение из-за того, что они выживают в предыдущем.

0

Я думаю, что эта цитата говорит: «Завершите свой блок работы и убейте свой экземпляр. Чтобы убить ваш экземпляр, вы должны очистить свою мусорную корзину из-за своей памяти».

Смежные вопросы