Почему C++ не имеет сборщика "мусора"?

258
задан Rakete1111 10 July 2017 в 08:45
поделиться

7 ответов

Неявная сборка "мусора", возможно, была включена, но она просто не сделала сокращение. Вероятно, из-за не только сложности реализации, но также и из-за людей, не бывших способных прийти к общему согласию достаточно быстро.

А заключают в кавычки от самого Bjarne Stroustrup:

я надеялся, что сборщик "мусора", который мог быть дополнительно включен, будет частью C++ 0x, но было достаточно технических проблем, что я должен суметь обойтись просто подробной спецификацией того, как такой коллектор интегрируется с остальной частью языка, если обеспечено. Как имеет место с по существу всем C++ 0x функции, экспериментальная реализация существует.

существует хорошее обсуждение темы здесь .

Общий обзор:

C++ очень мощен и позволяет Вам делать почти что-либо. Поэтому это автоматически не продвигает много вещей на Вас, которые могли бы повлиять на производительность. Сборка "мусора" может быть легко реализована с интеллектуальными указателями (возражает, что указатели обертки с подсчетом ссылок, которые автоматический удаляют себя, когда подсчет ссылок достигает 0).

C++ был создан с конкурентами в памяти, которые не имели сборки "мусора". Эффективность была основной озабоченностью, что C++ должен был парировать критику от по сравнению с C и другими.

существует 2 типа сборки "мусора"...

Явная сборка "мусора":

C++ 0x будет иметь сборку "мусора" через указатели созданной с shared_ptr

, Если Вы захотите его, можно использовать его, если Вы не хотите его, Вы не принуждены к использованию его.

можно в настоящее время использовать boost:shared_ptr также, если Вы не хотите ожидать C++ 0x.

Неявная сборка "мусора":

Это не имеет прозрачной сборки "мусора" все же. Это будет фокус для будущих спецификаций C++ все же.

, Почему Tr1 не имеет неявной сборки "мусора"?

существует много вещей, которые должен был иметь tr1 C++ 0x, Bjarne Stroustrup в предыдущих интервью заявил, что tr1 не имел столько, сколько ему понравится.

152
ответ дан 9 revs, 2 users 92% 23 November 2019 в 02:41
поделиться

Для ответа больше всего "почему" вопросы о C++ читайте Дизайн и Эволюция C++

8
ответ дан Nemanja Trifunovic 23 November 2019 в 02:41
поделиться

, Если Вы хотите автоматическую сборку "мусора", существуют хорошие сборщики "мусора" коммерческого и общественного достояния для C++. Для приложений, где сборка "мусора" подходит, C++ является превосходным собравшим "мусор" языком с производительностью, которая выдерживает сравнение с другим, собрал "мусор" языки. См. Язык Программирования на C++ (4 Выпусков) для обсуждения автоматической сборки "мусора" в C++. См. также, Hans-J. Boehm сайт для C и сборки "мусора" C++ ( архив ).

кроме того, C++ поддерживает методы программирования, которые позволяют управлению памятью быть безопасно и неявно без сборщика "мусора" . Я считаю сборку "мусора" последним выбором и несовершенным способом обработать для управления ресурсами. Это не означает, что это никогда не полезно, просто что существуют лучшие подходы во многих ситуациях.

Источник: http://www.stroustrup.com/bs_faq.html#garbage-collection

Что касается того, почему этому не встроили его, Если я помню правильно, это было изобретено, прежде чем GC был вещь , и я не полагаю, что язык, возможно, имел GC по нескольким причинам (Т.Е. Назад совместимость с C)

Hope, которой это помогает.

15
ответ дан Andriy Makukha 23 November 2019 в 02:41
поделиться

Одна из самых больших причин, что C++ не имеет созданным в сборке "мусора", - то, что то, чтобы заставлять сборку "мусора" играть по правилам с деструкторами действительно, действительно трудно. Насколько я знаю, никто действительно не знает, как решить его полностью все же. Существует много проблем для контакта с:

  • детерминированное время жизни объектов (подсчет ссылок дает Вам это, но GC не делает. Хотя это не может быть настолько большим из соглашения).
  • , что происходит, если деструктор бросает, когда объект собирается "мусор"? Большинство языков игнорирует это исключение, так как нет действительно никакого блока выгоды, чтобы быть в состоянии транспортировать его к, но это - вероятно, не приемлемое решение для C++.
  • , Как позволить/запретить его? Естественно это, вероятно, было бы решение времени компиляции, но код, который записан для GC по сравнению с кодом, который записан для НЕ GC, будет очень отличающимся и вероятно несовместимым. Как Вы согласовываете это?

Это всего несколько проблем, с которыми стоят.

34
ответ дан Greg Rogers 23 November 2019 в 02:41
поделиться

Какой тип? это должно быть оптимизировано для встроенных контроллеров стиральной машины, сотовых телефонов, рабочих станций или суперкомпьютеров?
это должно расположить по приоритетам gui скорость отклика или загрузку сервера?
это должно использовать большую память или много ЦП?

C/c ++ используется при просто слишком многих различных обстоятельствах. Я подозреваю, что что-то как интеллектуальные указатели повышения будет достаточно для большинства пользователей

Редактирование - Автоматические сборщики "мусора" не являются так проблемой производительности (можно всегда покупать больше сервера), это - вопрос predicatable производительности.
Не знание, когда GC собирается умереть, похоже на найм narcoleptic пилота авиакомпании, большую часть времени они являются великими - но когда Вам действительно нужна скорость отклика!

55
ответ дан Martin Beckett 23 November 2019 в 02:41
поделиться

Идея позади C++ состояла в том, что Вы не оплатите влияния производительности функции, которые Вы не используете. Так добавление сборки "мусора" означало бы иметь некоторые программы, запущенные прямо на аппаратных средствах, которые путь C делает и некоторые в своего рода виртуальной машине во время выполнения.

Ничто не препятствует тому, чтобы Вы использовали некоторую форму интеллектуальных указателей, которые связываются с некоторым сторонним механизмом сборки "мусора". Я, кажется, вспоминаю Microsoft, делающую что-то как этот с COM, и это не перешло в хорошо.

10
ответ дан Uri 23 November 2019 в 02:41
поделиться

Чтобы добавить к дискуссии здесь.

Есть известные проблемы со сборкой мусора, и их понимание помогает понять, почему их нет в C ++.

1. Производительность?

Первая жалоба часто касается производительности, но большинство людей не понимают, о чем они говорят. Как показано в Мартина Беккета , проблема может заключаться не в производительности как таковой, а в предсказуемости производительности.

В настоящее время широко используются 2 семейства сборщиков мусора:

  • Тип Mark-And-Sweep
  • Тип подсчета ссылок

Mark And Sweep работает быстрее (меньшее влияние на общая производительность), но он страдает синдромом «заморозить мир»: то есть, когда сборщик мусора срабатывает, все остальное останавливается до тех пор, пока сборщик мусора не произведет очистку. Если вы хотите создать сервер, который отвечает за несколько миллисекунд ... некоторые транзакции не оправдают ваших ожиданий :)

Проблема подсчета ссылок в другом: подсчет ссылок добавляет накладные расходы, особенно в многопоточных средах, потому что вам нужно иметь атомный счетчик. Кроме того, существует проблема эталонных циклов, поэтому вам нужен умный алгоритм для обнаружения этих циклов и их устранения (обычно реализуется также путем «замораживания мира», хотя и реже). В целом, на сегодняшний день этот тип (хотя обычно более отзывчивый или, скорее, зависает реже) медленнее, чем Mark And Sweep .

Я видел статью разработчиков Eiffel, которые пытались реализовать подсчет ссылок сборщик мусора, который имел бы такую ​​же глобальную производительность, что и Mark And Sweep без «Freeze The World» "аспект. Требовался отдельный поток для GC (обычно). Алгоритм был немного пугающим (в конце), но документ хорошо поработал, вводя концепции по одному и показывая эволюцию алгоритма от «простой» версии к полноценной. Рекомендую к прочтению, если бы я только мог снова положить руки на файл PDF ...

2. Получение ресурсов - это инициализация (RAII)

В C ++ распространена идиома, заключающаяся в том, что вы оборачиваете владение ресурсами внутри объекта, чтобы гарантировать, что они должным образом освобождены. Он в основном используется для памяти, так как у нас нет сборки мусора, но, тем не менее, он также полезен для многих других ситуаций:

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

Идея состоит в том, чтобы правильно контролировать время жизни объекта:

  • он должен быть живым, пока он вам нужен
  • он должен быть уничтожен, когда вы закончите с ним

Проблема GC в том, что если он помогает с первым и в конечном итоге гарантирует, что позже ... этого «конечного» может оказаться недостаточно.Если вы снимете блокировку, вам бы очень хотелось, чтобы она была снята сейчас, чтобы не блокировать дальнейшие вызовы!

У языков с GC есть два обходных пути:

  • не используйте GC, когда выделения стека достаточно: обычно это связано с проблемами производительности, но в нашем случае это действительно помогает, поскольку область действия определяет время жизни
  • с использованием ] ... но это явный (слабый) RAII, тогда как в C ++ RAII неявный, так что пользователь НЕ МОЖЕТ невольно совершить ошибку (опуская с использованием ключевого слова )

3. Умные указатели

Умные указатели часто используются как серебряная пуля для обработки памяти в C ++ . Часто я слышал: сборщик мусора нам не нужен, потому что у нас есть умные указатели.

Больше нельзя ошибаться.

Умные указатели действительно помогают: auto_ptr и unique_ptr используют концепции RAII, что действительно очень полезно. Они настолько просты, что вы легко можете написать их самостоятельно.

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

Это здорово, в конце концов, именно для этого Boost, но это не серебряная пуля. Фактически, основная проблема с shared_ptr заключается в том, что он имитирует сборщик мусора, реализованный с помощью подсчета ссылок , но вам нужно реализовать обнаружение цикла самостоятельно ...Urg

Конечно, есть эта штука weak_ptr , но я, к сожалению, уже видел утечки памяти, несмотря на использование shared_ptr из-за этих циклов ... и когда вы находитесь в Многопоточная среда, ее чрезвычайно сложно обнаружить!

4. Какое решение?

Не существует серебряной пули, но, как всегда, это определенно возможно. В отсутствие GC необходимо четко понимать принадлежность:

  • предпочитают иметь единственного владельца в один момент времени, если возможно,
  • если нет, убедитесь, что ваша диаграмма классов не имеет никакого цикла, относящегося к владению и разрыву их с тонким применением weak_ptr

Итак, действительно,было бы здорово иметь сборщик мусора ... однако это нетривиальная проблема. А пока нам остается только засучить рукава.

143
ответ дан 23 November 2019 в 02:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: