Основными недостатками использования сборщика мусора, на мой взгляд, являются:
Недетерминированная очистка ресурсов. Иногда удобно сказать: «Я закончил с этим, и я хочу, чтобы его почистили СЕЙЧАС». В случае с GC это обычно означает, что сборщик мусора должен все очистить или просто ждать, пока он не будет готов - и то, и другое отнимает у вас как у разработчика некоторый контроль.
Возможные проблемы с производительностью, возникающие из-за недетерминированной работы сборщика мусора. Когда сборщик мусора собирает данные, часто наблюдаются (небольшие) зависания и т. Д. Это может быть особенно проблематичным для таких вещей, как моделирование в реальном времени или игры.
У .NET есть два недостатка, которые я вижу.
1) Люди предполагают, что сборщик мусора знает лучше, но это не всегда так. Если вы сделаете определенные типы распределения, вы можете заставить себя испытать некоторые действительно неприятные программные смерти без прямого вызова GC.
2) Объекты размером более 85 КБ попадают в LOH или кучу больших объектов. Эта куча в настоящее время НИКОГДА не уплотняется, поэтому, опять же, ваша программа может столкнуться с исключениями из-за нехватки памяти, когда на самом деле LOH недостаточно уплотнен для того, чтобы вы могли сделать другое выделение.
Обе эти ошибки показаны в коде, который я опубликовал в этом вопросе:
Примите это от программиста на C... это касается затрат/выгод и соответствующего использования
В алгоритмах сборки мусора, таких как tri-color/mark-and-sweep, часто существует значительная задержка между "потерей" ресурса и освобождением физического ресурса. В некоторых случаях GC фактически приостанавливает выполнение программы для выполнения сборки мусора.
Будучи долгое время программистом на языке Си, я могу сказать вам:
a) Ручная сборка мусора free() трудна -- Это потому, что обычно существует большая доля ошибок в человеческом размещении вызовов free(), чем в алгоритмах GC.
b) Ручная сборка мусора free() стоит времени -- Перевешивает ли время, потраченное на отладку, миллисекундные паузы GC? Может быть, выгоднее использовать сборку мусора, если вы пишете игру, чем, скажем, встроенное ядро.
Но когда вы не можете позволить себе недостаток времени выполнения (нужные ресурсы, ограничения реального времени), то, вероятно, лучше выполнить ручное распределение ресурсов. Это может занять время, но может быть на 100% эффективным.
Попробуйте представить себе ядро ОС, написанное на Java? Или на .NET runtime с GC... Просто посмотрите, сколько памяти накапливает JVM при выполнении простых программ. Я знаю, что такие проекты существуют... просто от них меня немного тошнит.
Просто имейте в виду, что мой linux box сегодня с 3GB RAM делает практически те же вещи, что и с 512MB RAM несколько лет назад. Единственная разница в том, что у меня запущены mono/jvm/firefox и т.д. Бизнес-обоснование для GC очевидно, но мне все еще некомфортно от него большую часть времени.
Хорошие книги:
Dragon book (последнее издание), Modern Compiler Implementation in C
Если вы уверены (хорошо) в своих навыках управления памятью, то преимущества нет.
Концепция была введена для минимизации времени разработки и из-за отсутствия экспертов в программировании, которые досконально разбирались бы в памяти.
Практически невозможно заставить диспетчер памяти без сборщика мусора работать в многопользовательском режиме. -CPU среда, не требующая захвата и снятия блокировки каждый раз, когда память выделяется или освобождается. Каждое получение или снятие блокировки потребует, чтобы ЦП координировал свои действия с другими ЦП, и такая координация обычно обходится довольно дорого. Система, основанная на сборке мусора, может позволить выполнять много распределений памяти, не требуя каких-либо блокировок или другой координации между процессорами. Это большое преимущество. Недостатком является то, что многие шаги в сборке мусора требуют, чтобы ЦП координировал свои действия, а для достижения хорошей производительности обычно требуется, чтобы такие шаги были в значительной степени консолидированы (нет особой выгоды от устранения требования координации ЦП при каждом выделении памяти, если Процессоры должны координировать свои действия перед каждым шагом сборки мусора). Такая консолидация часто приводит к тому, что все задачи в системе приостанавливаются на разное время во время сбора; в общем, чем длиннее паузы, тем меньше времени потребуется на сбор данных.
Если бы процессоры вернулись к основанной на дескрипторах системе дескрипторов / указателей (аналогично той, что использовалась в 80286, хотя в настоящее время больше не будут использовать 16-битные сегменты), сборка мусора будет возможна одновременно. с другими операциями (если дескриптор использовался, когда сборщик мусора хотел его переместить, задача, использующая этот дескриптор, должна была быть заморожена, пока данные копировались со старого адреса на новый, но это не должно занять много времени) . Не уверен, что это когда-нибудь произойдет (кстати, если бы у меня были мои устройства, ссылка на объект была бы 32-битной, а указатель был бы ссылкой на объект плюс 32-битное смещение; я думаю, что пройдет некоторое время, прежде чем появится потребность в более чем 2 миллиардах объектов или в любом объекте размером более 4 гигабайт. Несмотря на закон Мура, если бы в приложении было более 2 миллиардов объектов, его производительность, вероятно, была бы улучшена за счет использования меньшего количества более крупных объектов. Если приложению потребуется объект более 4 гигабайт его производительность, вероятно, будет улучшена за счет использования большего количества объектов меньшего размера.)
Самая большая проблема, когда дело доходит до производительности (особенно в системах или системах реального времени), заключается в том, что ваша программа может испытывать некоторые неожиданные задержки, когда запускается сборщик мусора. Однако современные сборщики мусора стараются избежать этого и могут быть настроены в режиме реального времени. целей.
Еще одна очевидная вещь заключается в том, что вы не можете управлять своей памятью самостоятельно (например, выделять в локальной памяти numa), что вам может потребоваться при реализации низкоуровневого программного обеспечения.
Как правило, сборка мусора имеет определенные недостатки: