Если вы придерживаетесь стандартного кодирования в .NET, есть ли причина для ручного вызова GC или запуска финализаторов? - PullRequest
4 голосов
/ 25 мая 2010

Если вы придерживаетесь управляемого кода и стандартного кодирования (ничего, что не делает нетрадиционные вещи с CLR) в .NET, есть ли какая-либо причина для ручного вызова GC или запроса на запуск финализаторов на объектах, на которые нет ссылок?

Причина, по которой я спрашиваю, состоит в том, что у меня есть приложение, которое становится огромным в наборе рабочей памяти. Мне интересно, звонит ли

System.GC.Collect();

и

System.GC.RunFinalizers();

помогло бы, и если бы оно вызвало что-либо, что обычно не было бы сделано CLR.

Ответы [ 6 ]

7 голосов
/ 25 мая 2010

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

Попробуйте найти утечки памяти в вашей программе: хотя языки .NET управляются памятью, это не значит, что она всегда знает, когда вы больше не используете определенный объект. Например, объекты, присоединенные как слушатели событий к другим объектам, считаются корневыми для GC и не будут собираться.

Вы можете попробовать SOS для поиска утечек.

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

3 голосов
/ 25 мая 2010

@ zneak: На самом деле, это не совсем так. Я столкнулся с ситуацией, в которой у меня периодически и недетерминированно заканчивался недостаток памяти при работе с большим набором данных (который требовал большого количества создания и уничтожения управляемых объектов) в c #.

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

2 голосов
/ 25 мая 2010

Да, это полезно для написания модульных тестов, которые требуют, чтобы определенные методы Dispose / Finalize вызывались, например, детерминистически (как видно из вида вашего теста).

1 голос
/ 25 мая 2010

Также, System.GC.Collect (); полезно, если вы хотите измерить потребление памяти некоторыми контейнерами. Например, у вас есть хранилище базы данных и служба, которая кэширует проиндексированные фрагменты данных, которые загружаются последовательно и синхронно. Когда ваша служба находится под давлением памяти, она может выгружать большие фрагменты наименее недавно использованных данных.

1 голос
/ 25 мая 2010

Конечно, есть причина, иначе они не предоставили бы метод Collect (). Их мало и далеко между тем, хотя. Только когда-либо используйте его, когда вы знаете , что целая куча долгоживущих объектов, которые были бы переведены в поколение № 2, готовы к сбору. Или выпустить COM-объект, который имеет много ссылок, которые вы не можете отследить, если действительно будет выгружено. Или обойти грязный код, который не вызывает Dispose (), когда это необходимо.

Это редко.

0 голосов
/ 25 мая 2010

Оставьте это CLR. Используйте некоторые инструменты для выявления проблемы, о которой вы упомянули.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...