Должен ли я когда-нибудь вручную принудительно собирать мусор в своем приложении WPF? - PullRequest
11 голосов
/ 22 апреля 2011

Я только что разобрался с утечками памяти в моем приложении WPF.Для этого я использовал профилировщик CLR, а также наблюдал за статистикой процесса в диспетчере задач Windows.Мой основной тест состоял в том, чтобы убедиться, что когда определенное окно было закрыто, оно все еще не зависало в памяти.

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

Но это заставило меня задуматься - есть ли необходимость вручную принудительно собирать мусор?

Мне больно наблюдать, как увеличивается потребление памяти моим приложением, когда я открываю и закрываю окна.Конечно, в конце концов, сборщик мусора запускается автоматически и все улаживается.Но почти кажется хорошей идеей собирать мусор вручную после закрытия этих тяжелых окон.Но есть ли смысл?У меня такое ощущение, что в стороне от тестирования, мы не должны форсировать сборку мусора - просто дайте системе разобраться в этом.

Мысли оценены.

Ответы [ 6 ]

9 голосов
/ 23 апреля 2011

Спасибо за отзывы, ребята.Я согласен с вашим советом и позволю системе позаботиться о том, для чего предназначена система!

С тех пор я действительно нашел хороший ответ на свой вопрос в книге, которая у меня есть на.NET Framework.Там написано:

Цель сборщика мусора .NET - управлять памятью от нашего имени.Однако в некоторых очень редких случаях может быть полезно программно форсировать сборку мусора, используя GC.Collect().В частности:

  • Когда ваше приложение собирается ввести блок кода, который вы не хотите прерывать возможной сборкой мусора.
  • Когда ваше приложение только что завершило выделение чрезвычайно большого количества объектов и вы хотите удалить как можно большую часть полученной памяти.
5 голосов
/ 22 апреля 2011

Хорошая практика - никогда не форсировать сборку мусора вручную в любом приложении .NET.GC должен быть умнее нас (и на самом деле он умный).К сожалению, при утечке памяти даже принудительный вызов GC не помогает.

3 голосов
/ 22 апреля 2011

Я согласен с вами по обе стороны от вашей точки зрения :-).Я обычно придерживаюсь подхода, согласно которому люди, написавшие среду выполнения .NET, умнее меня и лучше понимают сборку мусора, чем я, поэтому я оставляю это в покое.люди думали , что добились успеха, форсируя сборку мусора, но не было никаких веских доказательств того, что это помогло.

2 голосов
/ 22 апреля 2011

Полагаю, вам следует прочитать эту статью: Секреты выделения памяти WPF .Это совсем не о вашем вопросе, но полезно для понимания поведения WPF.

2 голосов
/ 22 апреля 2011

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

В противном случае это бесполезно, потому что до сих пор GC умнее меня.

0 голосов
/ 22 апреля 2011

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

...