Как узнать, запущен ли сборщик мусора .Net 3.5? - PullRequest
2 голосов
/ 01 марта 2012

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

Приложение выделяет около 20 МБ при запуске.Но я много раз пытался загрузить большой файл узлов, и выделенная память превысила 700 МБ.Я думал, что смогу освободить память сборщиком мусора.

Машина, на которой я работаю, имеет 12 ГБ ОЗУ, так что, может быть, такой «маленький» объем выделяемой памятиЭто не имеет значения для GC.

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

Ответы [ 7 ]

7 голосов
/ 01 марта 2012

GC обычно запускается, когда происходит любой из следующих сценариев:

  • Вы вызываете GC.Collect (чего не следует делать)
  • Бюджет Gen0 исчерпан

Есть и другие сценарии, но пока я их пропущу.

Вы не сказали нам, как измеряли использование памяти, но если вы смотрите на использование памяти самим процессом (например, через диспетчер задач), то вы можете не увидеть ожидаемые цифры.Помните, что среда выполнения .NET по сути имеет свой собственный менеджер памяти, который обрабатывает использование памяти от имени вашего управляемого приложения.Среда выполнения старается проявить смекалку, чтобы не выделять и не освобождать память для ОС все время (это дорогостоящие операции). Этот вопрос также может быть актуален.

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

2 голосов
/ 01 марта 2012

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

2 голосов
/ 01 марта 2012

Ответ: утечка объектов или GC еще не нужно запускать?

Используйте профилировщик памяти, чтобы увидеть, какие объекты выделены.В качестве основного шага - форсировать сборку мусора (GC.Collect) и проверить, является ли выделенная память (GC.GetTotalMemory) разумной.

2 голосов
/ 01 марта 2012

Возможно, у вас есть управляемый эквивалент утечки памяти. Поддерживаете ли вы устаревшие ссылки на эти объекты (то есть, у вас есть List<T> или какой-либо другой объект, который отслеживает эти узлы)?

Является ли подписка на событие объекта, который не выходит за рамки? Ссылка на подписчика на событие сохраняется, поэтому, если вы не отсоедините его, ваши объекты останутся живыми.

Вы также можете забыть Dispose объектов, которые реализуют IDisposable. Не могу сказать, не увидев ваш код.

Точное поведение GC определяется реализацией. Вы должны разработать свое приложение так, чтобы оно не имело значения. Если вам нужно детерминированное управление памятью, значит, вы используете не тот язык. Используйте инструмент (подойдет профилировщик ANTS от RedGate), чтобы узнать, не пропускаете ли вы где-нибудь ссылки.

2 голосов
/ 01 марта 2012

Когда запускается сборщик мусора .Net 3.5?Я думал, что увижу сборщик мусора время от времени, освобождая память.

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

2 голосов
/ 01 марта 2012

enter image description here

Этот комикс - лучший способ объяснить эту тему:)

1 голос
/ 02 марта 2012

Вы можете отслеживать активность сборщика мусора в .NET 4.0 и более поздних версиях с помощью GC.RegisterForFullGCNotification, как описано в этой ссылке: http://www.abhisheksur.com/2010/08/garbage-collection-notifications-in-net.html

...