Обработчик событий и утечки памяти - PullRequest
6 голосов
/ 05 февраля 2010

Я анализирую проект VB.NET, и есть некоторые объекты (дочерняя MDI форма), которые удаляются, но не удаляются GC .

Анализ MemoryProfiler обнаружил, среди прочего, следующее:

"Этот экземпляр утилизирован и все еще косвенно укорененный EventHandler. Это часто указывает на то, что EventHandler не был должным образом удалены и является частой причиной утечки памяти. Примеры ниже непосредственно укоренены EventHandler (s). Исследуйте их, чтобы получить больше информация об этой проблеме ... "

Теперь я пытаюсь понять, что это должно значить и как это исправить.

У меня есть форма MDI и дочерняя форма. Дочерняя форма не собирается GC после открытия / закрытия, по-видимому, потому что она все еще (косвенно?) Ссылается на MDIForm EventHandlerList ...

Что это может быть и как мне это исправить?

Я попробовал исправление, рекомендованное в этой теме , потому что была проблема со ссылкой MDI в PropertyStore, теперь это устранено, но появилась ссылка MDI EventHandlerList на дочернюю форму .

После некоторого анализа кода я заметил

AddHandler newMenu.Click, AddressOf ClickMenu

без предшествующего с RemoveHandler newMenu.Click, AddressOf ClickMenu. Может ли это быть основной причиной?

И, предложение, это Handles

Private Sub ClickMenu(sender as Object, e as EventArgs) Handles newMenu.Click

лучше, чем

RemoveHandler newMenu.Click, AddressOf ClickMenu
AddHandler newMenu.Click, AddressOf ClickMenu

с точки зрения выделения памяти?

Ответы [ 2 ]

4 голосов
/ 05 февраля 2010

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

Я ожидаю, что дочерняя форма отслеживала, когда ее родитель может закрыться (это обычный вариант использования), и не отписалась от FormClosingили FormClosed событие, когда оно получило это событие.Однако это только предположение.Чтобы подтвердить, посмотрите на реализацию вашей дочерней формы и найдите все случаи, когда она подписывается на события из родительской формы, а затем убедитесь, что есть соответствующая отмена подписки на эти события.

Обновление * 1010Обнаруженный вами обработчик меню, который не был удален, может быть корнем проблемы, которую вы видите.Попробуйте добавить вызов удаления и посмотрите, устраняет ли это утечку.

2 голосов
/ 05 февраля 2010

Есть еще один объект, который ссылается на объект, который должен быть удален GC через обработчик событий. Значение: есть еще один объект, который все еще подписан на событие удаленного объекта.

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

...