Почему RAII и сборка мусора являются взаимоисключающими? - PullRequest
6 голосов
/ 12 января 2011

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

Можете ли вы дать мне объяснение, почему не существует языков для сбора мусора с детерминированными деструкторами?

Ответы [ 3 ]

3 голосов
/ 17 января 2011

Они НЕ являются взаимоисключающими. Не стесняйтесь использовать C ++ с libgc (сборщик Boehm-Reiser-Detlefs). Вы по-прежнему можете использовать RAII, интеллектуальные указатели и ручное удаление, но, запустив GC, вы также можете просто «забыть» удалить некоторые объекты.

@ В ответе Энди о том, что ресурсы распределяются слишком поздно, упущен важный момент: семантически важна не задержка освобождения ресурсов, а порядок их освобождения.

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

Тем не менее, у Ocaml GC есть интересная возможность, где вы можете прикрепить финализатор к объекту. Если объект становится недоступным, запускается финализатор, однако объект не удаляется (потому что финализатор может сделать его снова доступным: в этом случае вы даже можете подключить другой финализатор). Эти финализаторы могут обеспечить некоторый контроль над порядком.

0 голосов
/ 12 января 2011

Сборщик мусора не может работать все время (пересчет становится ближе, но обычно не считается сборщиком мусора), поэтому он даже не пытается. Это просто непрактично. Следовательно, существует неизбежная задержка между тем, что объект становится недоступным (например, из-за того, что единственная ссылка выходит из области видимости), и сборщик мусора собирает его, возможно, с помощью финализатора. Эта задержка не является детерминированной ... если (а затем возможно детерминированное уничтожение в самом строгом смысле этого слова, хотя и нецелесообразно) заставить GC войти в детерминированный график - но это довольно близко к "GC, работающему постоянно" , что до сих пор невероятно непрактично.

Таким образом, GC и детерминированная очистка являются взаимоисключающими, потому что GC выполняет всю очистку, и он не может позволить себе быть детерминированным, но должен полагаться на максимизацию своей эффективности.

0 голосов
/ 12 января 2011

Из Википедии , отметив, что трассировка сборщиков мусора является наиболее распространенным типом:

Трассировка сборки мусора не детерминированный. Объект, который становится право на сборку мусора будет обычно убираются в конце концов, но нет гарантии, когда (или даже если) это произойдет.

Следовательно, использование RAII может привести к тому, что ресурс будет утилизирован слишком поздно.

В результате, например, в Java есть рекомендация «избегать финализаторов» (пункт 6 в «Эффективной Java» Джосуа Блоха). «В финализаторе не должно быть ничего критичного по времени».

...