Утечка памяти при построении объекта в .NET - PullRequest
1 голос
/ 14 октября 2010

http://www.devx.com/tips/Tip/5573

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

Ответы [ 5 ]

2 голосов
/ 14 октября 2010

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

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

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

В любом случае, мой ответ на ваш вопрос будет таким: нет, у вас нет утечки памяти.Я думаю, что вы можете увидеть увеличение использования памяти (что отличается от утечки памяти!).Память может быть восстановлена, но неправильное использование сборщика мусора, вероятно, задерживает этот процесс, и поэтому использование вашей памяти выше, чем могло бы быть.

0 голосов
/ 27 октября 2010

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

В vb.net можно «переправить» копию строящегося объекта в метод, вызывающий конструктор;таким образом, можно гарантировать, что Dispose будет вызван для объекта, который добавляет конструкторы или инициализаторы (метод Dispose должен быть подготовлен для работы с возможностью не полностью инициализированного объекта, а Dispose должен отменить любые подписки на события и Dispose any 'принадлежащие 'iDisposable объекты).В C # я не знаю никакого способа контрабанды копии строящегося объекта, кроме как с помощью переменной ThreadStatic или какого-либо другого kludge, и я не знаю ни одного способа для базового класса, чтобы гарантировать, что конструктор производного класса победил 'исключение.

0 голосов
/ 15 октября 2010

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

Помните, что значение «Использование памяти» в TaskManager записывает «рабочий набор», то есть объем физической памяти, используемой программой, который изменяется в зависимости от использования памяти всеми другими программами и файловым кешем. Вы должны следить за «частными байтами» программы, которые представляют собой объем памяти, выделяемый программой для хранения данных, которые могут быть сопоставлены с физической памятью или на диске в файле подкачки. Это «Размер виртуальной машины» в диспетчере задач. Лучше всего следить за счетчиками производительности .Net, которые покажут, сколько памяти имеет ваша программа в каждом поколении GC. Один из простых способов увидеть их - использовать Process Explorer. Вы увидите, что цикл в конструкторе TestClass может заполнить кучу 0-го поколения, а некоторые объекты перейдут в 1-е поколение до следующего GC. Но Поколение 2 останется пустым, и именно там вы найдете протекающие объекты, если они там есть.

0 голосов
/ 14 октября 2010

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

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

0 голосов
/ 14 октября 2010

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

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

...