Короткоживущие объекты

Каковы накладные расходы на создание множества временных объектов (т. е. для промежуточных результатов), которые «умирают молодыми» (никогда не переходят в следующее поколение в течение интервала сборки мусора)? Я предполагаю, что «новая» операция очень дешевая, так как на самом деле это просто приращение указателя. Однако каковы скрытые издержки борьбы с этим временным «мусором»?


person Tony the Pony    schedule 10.03.2009    source источник
comment
Если у вас действительно есть простые объекты, и особенно если их легко сбросить, создайте пул объектов и используйте их повторно. Это может работать и для сложных объектов. Когда-то у меня было приложение, которое делало тысячи маленьких растровых изображений для рисования промежуточного текста, который нельзя было нарисовать прямо на странице по логическим причинам. Для 1000 страниц размеры использовались повторно. Вместо «распоряжаться» я сохранил их в «свободной» хеш-таблице с ключом WidthxHeight (указывал на список растровых изображений) и проверил его перед выполнением NEW. Если есть, удалите его, используйте. Звучит дорого, но делать растровые изображения должно быть хуже. Огромное ускорение.   -  person FastAl    schedule 22.07.2010
comment
@FastAl Я предполагаю, что вы имеете в виду что-то вроде System.Drawing.Bitmap, который "инкапсулирует растровое изображение GDI+", что подразумевает что-то вроде syscal для их создания/уничтожения. Это сильно отличается от чистых объектов .net, о которых, как я полагаю, спрашивает ОП.   -  person binki    schedule 02.06.2017
comment
@binki - Вы правы насчет растрового изображения, конечно, это гораздо дороже, чем простые объекты. Но если цикл достаточно тугой и вы мало что делаете с объектами... увеличение скорости все же может стоить их повторного использования. GC все еще должен в конечном итоге что-то сделать. Конечно, в этом случае, это зависит. Он не упоминает размер, растровые изображения могут быть временными, и, как вы упомянули, за них взимается довольно скрытая стоимость. Новые объекты, если они большие, также могут быть очищены перед использованием, если ваш код перезаписывает то, что там есть, в любом случае это может означать 2-кратное ускорение (это своего рода ниндзя).   -  person FastAl    schedule 06.06.2017
comment
@FastAl - я бы изменил ваш ответ, сказав, что пул объектов имеет смысл, если (а) создавать или уничтожать объекты дорого, и (б) вашему приложению, вероятно, снова понадобится такое же количество этих объектов в ближайшее время. Определение дороговизны в (а) заключается в том, что профилирование показывает, что значительная часть вашего общего времени тратится на создание/уничтожение объектов. Иначе зачем заморачиваться?   -  person ToolmakerSteve    schedule 02.04.2018
comment
@ToolmakerSteve прямо на Стиве, это все предпосылки «в моей голове», которые я не подумал сказать. Мой оригинальный комментарий больше не редактируется.   -  person FastAl    schedule 05.04.2018


Ответы (6)


Немного — сборщик мусора очень быстрый для gen0. Он также настраивает себя, регулируя размер gen0 в зависимости от того, сколько ему удается собрать каждый раз, когда он идет. (Если ему удалось собрать много, он уменьшит размер gen0, чтобы в следующий раз собрать раньше, и наоборот.)

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

person Jon Skeet    schedule 10.03.2009
comment
Downvoters: комментарии приветствуются, иначе никто (включая меня) не узнает, с чем вы не согласны в моем ответе... - person Jon Skeet; 10.03.2009
comment
Он почти наверняка уже установлен на вашем компьютере с Windows. Нажмите Windows-R и просто введите perfmon. В противном случае его поиск будет зависеть от того, какую версию Windows вы используете. - person Jon Skeet; 10.03.2009
comment
Я понятия не имел, что вы можете использовать монитор производительности для мониторинга сборки мусора. Это может быть полезно. - person Aaron Smith; 10.03.2009
comment
Существует огромное количество счетчиков производительности для .NET. Это действительно впечатляет. - person Jon Skeet; 10.03.2009
comment
Если кто-то все еще читает это ;-), вы всегда можете получить еще больше подробностей с помощью профилировщика CLR - stackoverflow.com/questions/43220090/ очень полезно и полезно для оптимизации. - person FastAl; 06.06.2017

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

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

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

person Brian Rasmussen    schedule 10.03.2009
comment
ИМХО, у вас есть самая важная строка в любом ответе здесь: Стоимость генерации большого количества .. объектов - это более частая сборка мусора.... Почему это важно, потому что это не просто объекты, создаваемые кодом, который пишется в данный момент. Если более ранняя сборка мусора приводит к тому, что объекты из откуда в вашем коде переживают Gen0, которые умерли бы в Gen0, если бы между сборками было немного больше времени, это потенциально может быть существенной стоимостью. - person ToolmakerSteve; 02.04.2018

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

«Новая» операция на самом деле состоит из нескольких вещей:

  1. выделение памяти
  2. запуск конструктора типов
  3. возврат указателя на память
  4. увеличение следующего указателя объекта
person Scott Dorman    schedule 10.03.2009

Хотя новая операция спроектирована и написана эффективно, она не бесплатна и требует времени для выделения новой памяти. Библиотека выделения памяти должна отслеживать, какие фрагменты доступны для выделения, а вновь выделенная память обнуляется.

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

Вот статья из MSDN о том, как это работает: http://msdn.microsoft.com/en-us/magazine/bb985011.aspx

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

person Stephen Curial    schedule 10.03.2009
comment
Из связанной статьи: Эти тесты также показывают, что на Pentium 200 МГц требуется менее 1 миллисекунды для выполнения полного GC поколения 0. Цель Microsoft состоит в том, чтобы GC занимал не больше времени, чем обычная ошибка страницы. Вряд ли очень дорого ИМО. Не бесплатно, конечно, но если (продолжение) - person Jon Skeet; 10.03.2009
comment
код более удобочитаем с большим количеством мелких, недолговечных объектов, тогда я предпочел бы идти по этому пути, пока не будет доказано, что он является узким местом, чем изменить форму моего дизайна, чтобы противодействовать производительности. проблема, которая может вообще не быть проблемой. - person Jon Skeet; 10.03.2009
comment
Я согласен, и я не говорю, что они должны изменить то, как они пишут программы. Вопрос задавался, каковы основные накладные расходы, и я попытался дать ответ. - person Stephen Curial; 10.03.2009
comment
Я также изменил комментарий об очень дорогом, чтобы он не был таким сильным. 1 мс на чипе с частотой 200 МГц по-прежнему составляет сотни тысяч циклов, а с учетом текущей проблемы с памятью GC на современных компьютерах занимает миллионы циклов процессора. - person Stephen Curial; 10.03.2009
comment
Миллионы даже за просто коллекцию gen0? Это звучит больше, чем я ожидал. Мне было бы интересно прочитать больше, хотя - у вас есть какие-нибудь ссылки? - person Jon Skeet; 10.03.2009
comment
Вот классический обзор: PR Wilson, Методы сборки мусора для однопроцессорных систем, Международный семинар по управлению памятью. В документе рассматриваются многие алгоритмы GC и отмечается, что GC обычно добавляет дополнительные 5–20 % времени выполнения и 40–280 % служебной памяти. - person Stephen Curial; 11.03.2009
comment
Вот еще одна более свежая статья: cis.udel.edu/~cavazos/ismm- 07.pdf GC оказывает значительное влияние на общее время выполнения... В самом крайнем случае, одна конфигурация... тратит 89% времени выполнения на выполнение GC. Средняя доля времени выполнения, затрачиваемого на сборщик мусора, составляет 12,2%... - person Stephen Curial; 11.03.2009
comment
Да, но тут речь о Gen 0, а не о GC вообще - person Yola; 07.05.2019

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

person Andrew Hare    schedule 10.03.2009

Сборка мусора в .Net осуществляется по поколениям. Короткоживущие объекты будут собираться первыми и часто. Коллекция Gen 0 дешева, но в зависимости от масштаба количества объектов, которые вы создаете, она может быть довольно дорогостоящей. Я бы запустил профилировщик, чтобы узнать, влияет ли он на производительность. Если это так, рассмотрите возможность переключения их на структуры. Их не нужно собирать.

person Michael Meadows    schedule 10.03.2009