Подтвердить что ты не робот

Когда НЕ использовать сбор мусора?

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

4b9b3361

Ответ 1

Можно использовать сборку мусора с жестким реальным временем, если у вас есть полностью инкрементный сборщик мусора с ограниченным временем выполнения на каждый бит выделенной памяти, поэтому, сумасшедший, это НЕ обязательно причина не использовать сборку мусора:)

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

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

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

Наконец, сборщик мусора, конечно, потребляет процессорное время:) Итак, если вы можете закодировать управление памятью вручную, вы можете сохранить циклы процессора, которые собирал сборщик мусора:)

Ответ 2

Временное безумие?

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

В наши дни есть программные анализы, которые позволят компилятору сделать это за вас, но если вы пишете код C, вы делаете это вручную. Там была реализация с примерами в Dave Hanson C Интерфейсы и реализации, и она использовалась в Fraser и Hanson lcc компилятор, который написан на C без сборщика мусора.

Ответ 3

При программировании для встроенных устройств с ограниченными ресурсами. Например, iPhone использует подсчет ссылок.

Или при программировании чего-то чрезвычайно интенсивного на вашем компьютере. SETI @Home и видеоигры приходят на ум.

Я бы посоветовал вам не управлять своей собственной памятью, если ситуация не требует ее реальной необходимости. Кто-то известный однажды сказал, что код в два раза сложнее отлаживать, поскольку он должен писать. Ну, в первую очередь, управление памятью достаточно сложно.:)

Ответ 4

Единственная причина, по которой НЕ использовать Garbage Collection для управления ресурсами, - это если вы хотите использовать RAII ala С++, но, поскольку она применяется исключительно к памяти, даже тогда разумная идея ее использовать. (Примечание: это все еще возможно, поскольку gotcha связан с недетерминированной финализацией).

Тем не менее, использование Garbage Collection может использовать больше памяти, чем это строго необходимо, поэтому в сильно ограниченных объемах памяти, где нельзя даже освободить память для управления процедурами GC (и кода), тогда это хорошая причина не для того, чтобы используйте его тоже.

Кроме того, если используемый вами язык не содержит GC по умолчанию, например С++, и вам нравится использовать RAII, тогда это разумная причина, хотя для некоторых проблем это может быть очень полезно.

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

Ответ 5

Эмм... мой профессор рассуждает о том, чтобы сделать нашу (его учеников) жизнь сложнее и научить нас "настоящей вещи". Ха-ха:)

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

Ответ 6

Есть ли другие, менее обсуждаемые, веские причины, по которым кто-то предпочел бы ручное управление памятью вместо GC?

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

Например, следующая программа F # создает массив из 10 000 ints и затем обменивает их:

do
  let xs = Array.init 10000 int
  let timer = System.Diagnostics.Stopwatch.StartNew()
  for i=0 to xs.Length-2 do
    for j=i+1 to xs.Length-1 do
      let t = xs.[i]
      xs.[i] <- xs.[j]
      xs.[j] <- t
  printfn "%f" timer.Elapsed.TotalSeconds

Измените значение int на string, и программа будет работать в 2 раза медленнее, потому что ints можно обменять напрямую, тогда как обмен ссылочными типами должен иметь два барьера записи.

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

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

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

Ответ 7

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

Ответ 8

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

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

Ответ 9

Один из возможных ответов: "Где безопасность/стабильность системы не является основным требованием".

Имейте в виду, что приложения, которым предоставляется свободное владение над памятью, могут вызывать всевозможные проблемы безопасности, в том числе просто распределять и не освобождать память (DoS-атака, замедляя систему до остановки через недостаточный доступный ресурс памяти). Это ключевая часть модели безопасности Java, например, ее GC гарантирует, что этого никогда не произойдет.

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

Ответ 10

Сбор мусора против утечек

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

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

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

Комплексное управление ресурсами

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

В этих случаях эти постоянные объекты часто хранят дескрипторы/ссылки на ресурсы в системе, возможно, другие объекты, живущие на графике стойких сцен. В таких сценариях вы можете иметь центральный ресурс R, как сложную трехмерную модель, которая занимает сотни мегабайт оперативной памяти, к которой обращаются многие разные части сцены и пользовательский интерфейс. Например, как камера, так и светлый объект могут хранить список ссылок на объекты для исключения из камеры и системы освещения, из которых могут быть включены такие сложные 3D-модели.

В этих случаях и в командной среде для 3 отдельных разработчиков не слишком редко приходится писать код, который хранит постоянные дескрипторы/ссылки на R в десятках разных мест в коде. Когда пользователь удаляет R, все эти места должны освобождать дескриптор/ссылку.

Без сбора мусора, если один из них не сможет этого сделать (возможно, у него был плохой день, он был одним из менее опытных разработчиков, был в сжатом сроке с высоким давлением с более слабыми критериями тестирования и обзора, независимо от того, причина), оборванный указатель/дескриптор/ссылка оставлены. Доступ к ней приведет к сбою приложения с помощью segfault. Трассировка такого segfault с помощью отладчика часто сразу же показывает, где и почему это произошло.

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

Чтобы сбой или не сбой

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

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

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

Ответ 11

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