Разделите и завоюйте больших объектов для производительности GC

На моей работе мы обсуждаем разные подходы к чистке большой суммы управляемой памяти ~50-100MB. Существует два подхода к таблице (чтение: два старших devs не могут согласиться), и не наличие остальной части опыта команды не уверено в том, какой подход более желателен, производительность или пригодность для обслуживания.

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

Подход № 1: Удостоверьтесь, что все ссылки на объекты в блобе разъединены и позволяют GC обработать блоб и все соединения.

Подход № 2: Реализуйте IDisposable на этих объектах, затем звонят, располагают на этих объектах и устанавливают ссылки ни на Что и удаляют обработчики.

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

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

Я чувствую, что это - случай предварительной оптимизации, но я не знаю, что достаточно GC знает то, что действительно помогает или препятствует ему.

Править: для добавления акцента, "блоб" памяти не является ни одним большим объектом, это - много маленьких объектов, выделенных отдельно.

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

5
задан Apeiron 24 March 2010 в 23:58
поделиться

6 ответов

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

К сожалению, IDisposable не имеет ничего общего со сборкой мусора . Речь идет исключительно об освобождении неуправляемых ресурсов. Похоже, ваш второй старший разработчик пытается быть немного «слишком умным» для их же блага.

Первый подход должен подойти. Как только вы перестанете ссылаться на «blob», каждый объект в блоге станет некорневым, и его следует очистить.Это может произойти в неопределенное время после того, как вы освободите ссылку (если вы явно не укажете сборщику мусора для сбора, что я не рекомендую). Взаимозависимости будут правильно обработаны для вас.

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

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

9
ответ дан 18 December 2019 в 09:48
поделиться

Ни один из подходов не имеет смысла. У GC нет проблем с обнаружением циклических ссылок или сложных графов объектов. Нет смысла устанавливать ссылки на null. IDisposable ничего не делает для улучшения производительности GC.

Если и есть какое-либо указание на то, как вы решили проблему, так это установка события на ноль. У них есть умение сохранять ссылки на объекты, если они реализованы «задом наперед». Другими словами: сохранить в живых создателя события и уничтожить его клиентов. В таком случае отказ от подписки должен быть сделан явно.

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

3
ответ дан 18 December 2019 в 09:48
поделиться

Интерфейс IDisposable не имеет никакого отношения к сборке мусора.

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

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

Следовательно, создание объектов IDisposable не повлияет на то, как объекты собирают мусор. Даже использование метода Dispose для очистки всех ссылок практически не повлияет на запуск сборщика мусора; просто очистка ссылок на ваш блоб позволит всем вашим более мелким объектам сразу стать бесполезными.

2
ответ дан 18 December 2019 в 09:48
поделиться

Подход № 2: Реализуйте IDisposable для этих объектов, затем вызовите dispose для этих объектов и установите ссылки на {{1 }} Ничего и удаляем обработчики.

...

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

Я думаю, что это неправда; Стоимость сборщиков мусора обычно зависит от количества живых объектов и их ссылок, а также количества мертвых объектов (в зависимости от типа GC). Если вам не нужен объект (или объекты) и вы отрезаете пути ссылок от корневых объектов к нему / им, количество ссылок между «мусорными» объектами не имеет значения. Так что, я бы сказал, просто убедитесь, что не будет свисающих ссылок извне «капель», и все будет в порядке.

1
ответ дан 18 December 2019 в 09:48
поделиться

Microsoft подразумевает, что Dispose быстрее, чем Finalize, если вам нужна производительность для объектов, содержащих неуправляемые ресурсы (дескрипторы файлов, дескрипторы GDI и т. Д.). Я не думаю, что это то, чего вы пытаетесь достичь (вы ничего не сказали о неуправляемых ресурсах).

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

1
ответ дан 18 December 2019 в 09:48
поделиться
1
ответ дан 18 December 2019 в 09:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: