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

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

В настоящее время я пишу документ для своей компании о том, как избежать вызова сборщика мусора непосредственно из кода (например, при воспроизведении с COM-объектами).

Я знаю, что это плохая практика, и ее следует рассматривать только в очень редких случаях, но я не могу найти способ сказать, почему ее следует избегать. И я не хочу полагаться на принцип "The G.C. умнее вас" (даже если это правда:-))

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

Спасибо заранее!

Изменить: все те, которые вы предоставили до сих пор, действительно полезны. Как я не могу подтвердить всех (или я могу?), Что мне делать? Создать сообщество wiki?

4b9b3361

Ответ 1

Обычный аргумент производительности выполняется таким образом:

Generational GC являются быстрыми, потому что они полагаются на эвристику, что многие выделенные объекты недолговечны (объект "живой" до тех пор, пока он доступен, точка GC предназначена для обнаружения "мертвых" объектов и восстановления их Память). Это означает, что объекты могут накапливаться в специальной области ( "молодое поколение" ); GC запускается, когда эта область заполнена, и удаляет живые объекты, перемещая их ( "физически" ) в старое поколение. В большинстве поколений GC эта операция подразумевает паузу ( "stop-the-world" ), которая допустима, потому что она короткая (молодое поколение имеет ограниченный размер). Тот факт, что мир приостановлен во время собрания молодого поколения, позволяет эффективно обрабатывать молодые объекты (а именно, чтение или запись ссылки в юных объектных полях - это простой доступ к памяти, не требующий учета параллельного доступа из потока GC или инкрементная метка и развертка).

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

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

Ответ 2

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

Учитывая, что это ситуация, когда легче получить лучшую производительность, кажется мне неинтересным!

NB. Когда вы играете с объектами COM, вызов GC напрямую вряд ли поможет решить вашу проблему. Если объекты COM висят вокруг, тогда они имеют ненулевые значения ref, и никакие дополнительные вызовы GC не исправят это.

Ответ 3

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

Все, что требует времени и сборщик мусора, будет работать только тогда, когда оно определяет, что преимущество больше, чем вред.

Когда вы вызываете GC самостоятельно, вы, скорее всего, просто назовете его слишком часто, и это увеличит время, затрачиваемое на GC, и уменьшит время, потраченное в вашей программе.

Ответ 4

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