Как сократить время, затрачиваемое на сборку мусора

Я создаю настольное приложение, которое требует больших вычислительных ресурсов и может выполняться в течение нескольких секунд. Очевидно, необходимо минимизировать время этой операции. Операцию довольно легко распараллелить (отдельные подзадачи), и каждая подзадача занимает около 50 мсек в одном потоке. В нескольких потоках каждая подзадача занимает в 4-5 раз больше времени, потому что 40-50% времени тратится на сборку мусора, что фактически полностью отменяет ускорение.

Так что мне нужно дать GC меньше работы. Моя первая мысль заключалась в том, чтобы попытаться найти, какой тип объекта чаще всего подвергается сборке мусора, но я понял, что, хотя я часто занимаюсь профилированием памяти, я никогда не искал подобный шаблон.Обычно смотрят на снимки кучи или различия между снимками кучи, но они показывают живые объекты, а не объекты, которые были созданы и размещены между этими снимками. Итак, это мой первый вопрос: как проще всего определить, какие типы создаются и собираются чаще всего? Я попытался найти количество вызовов методов, чтобы узнать, вызывается ли какой-либо конструктор подозрительно часто, но все объекты, созданные миллионами, были только небольшими типами структур. Они не должны влиять на сборщик мусора, даже если я правильно понимаю их, даже если они помещены в рамку?

Алгоритм создает сотни тысяч отдельных объектов точек результата. Это, конечно, не должно быть gc'd, потому что они представляют собой результат операции. Но это подводит меня ко второму вопросу: зависит ли время, проведенное в сборке мусора, от общего количества объектов или от количества фактически собранных объектов? Следует ли мне попытаться ограничить количество объектов результата и вместо этого использовать меньшее количество объектов результата, но большего размера?

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

. Правка: я должен пояснить, что проблема с производительностью заключается в том, что выполнение эффективно сериализуется на сборщике мусора рабочей станции. См., Например, проблему производительности, описанную в этом посте.

http://blogs.msdn.com/b/hshafi/archive/2010/06/17/case-study-parallelism-and-memory-usage-vs2010-tools-to-the-rescue.aspx

Я ничего не могу сделать, чтобы сборщик мусора блокировал мои потоки (и я не думаю, что мне нужен серверный сборщик мусора для настольного приложения, верно?). Итак, чтобы получить линейное ускорение для этой операции, мне нужно уменьшить количество вызовов GC. Большая часть потраченного впустую времени фактически тратится впустую из-за того, что другие потоки заблокированы, ожидая, пока один поток выполнит сборку мусора.

8
задан dthorpe 14 November 2011 в 04:27
поделиться