Каковы накладные расходы на создание множества временных объектов (т. е. для промежуточных результатов), которые «умирают молодыми» (никогда не переходят в следующее поколение в течение интервала сборки мусора)? Я предполагаю, что «новая» операция очень дешевая, так как на самом деле это просто приращение указателя. Однако каковы скрытые издержки борьбы с этим временным «мусором»?
Короткоживущие объекты
Ответы (6)
Немного — сборщик мусора очень быстрый для gen0. Он также настраивает себя, регулируя размер gen0 в зависимости от того, сколько ему удается собрать каждый раз, когда он идет. (Если ему удалось собрать много, он уменьшит размер gen0, чтобы в следующий раз собрать раньше, и наоборот.)
Окончательный тест заключается в том, как работает ваше приложение. Здесь очень удобен Perfmon, показывающий, сколько времени было потрачено на сборщик мусора, сколько коллекций было создано для каждого поколения и т. д.
Как вы говорите, само размещение очень недорогое. Стоимость создания большого количества короткоживущих объектов — более частые сборщики мусора, поскольку они запускаются, когда бюджет поколения 0 исчерпан. Однако коллекция поколения 0 довольно дешева, поэтому, пока ваш объект действительно недолговечен, накладные расходы, скорее всего, не будут значительными.
С другой стороны, распространенный пример объединения большого количества строк в цикл значительно увеличивает нагрузку на сборщик мусора, поэтому все зависит от количества создаваемых вами объектов. Не помешает подумать о распределении.
Стоимость сборки мусора заключается в том, что управляемые потоки приостанавливаются во время уплотнения.
В общем, это не то, о чем вам, вероятно, следует беспокоиться, и звучит так, как будто это начинает очень близко подходить к «микрооптимизации». Сборщик мусора был разработан с предположением, что «хорошо настроенное приложение» будет иметь все свои распределения в Gen0, что означает, что все они «умрут молодыми». Каждый раз, когда вы выделяете новый объект, он всегда находится в Gen0. Сбор не произойдет до тех пор, пока пороговое значение Gen0 не будет превышено и в Gen0 не будет достаточно свободного места для хранения следующего выделения.
«Новая» операция на самом деле состоит из нескольких вещей:
- выделение памяти
- запуск конструктора типов
- возврат указателя на память
- увеличение следующего указателя объекта
Хотя новая операция спроектирована и написана эффективно, она не бесплатна и требует времени для выделения новой памяти. Библиотека выделения памяти должна отслеживать, какие фрагменты доступны для выделения, а вновь выделенная память обнуляется.
Создание большого количества объектов, которые умирают молодыми, также будет чаще запускать сборку мусора, и эта операция может быть дорогостоящей. Особенно со сборщиками мусора "останови мир".
Вот статья из MSDN о том, как это работает: http://msdn.microsoft.com/en-us/magazine/bb985011.aspx
Примечание: в нем описывается, насколько затратным является вызов сборки мусора, потому что ему необходимо построить граф объектов, прежде чем он сможет начать сборку мусора.
Если эти объекты никогда не будут продвигаться из поколения 0, вы увидите довольно хорошую производительность. Единственная скрытая стоимость, которую я вижу, заключается в том, что если вы превысите свой бюджет поколения 0, вы заставите сборщик мусора сжимать кучу, но сборщик мусора будет самонастраиваться, так что это не является большой проблемой.
Сборка мусора в .Net осуществляется по поколениям. Короткоживущие объекты будут собираться первыми и часто. Коллекция Gen 0 дешева, но в зависимости от масштаба количества объектов, которые вы создаете, она может быть довольно дорогостоящей. Я бы запустил профилировщик, чтобы узнать, влияет ли он на производительность. Если это так, рассмотрите возможность переключения их на структуры. Их не нужно собирать.
System.Drawing.Bitmap
, который "инкапсулирует растровое изображение GDI+", что подразумевает что-то вроде syscal для их создания/уничтожения. Это сильно отличается от чистых объектов .net, о которых, как я полагаю, спрашивает ОП. - person binki   schedule 02.06.2017