Я анализирую проект 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
. Это могла быть основная причина?
И, propos, Handles
Private Sub ClickMenu(sender as Object, e as EventArgs) Handles newMenu.Click
лучше это
RemoveHandler newMenu.Click, AddressOf ClickMenu
AddHandler newMenu.Click, AddressOf ClickMenu
с точки зрения выделения памяти?
EventHandlerList
используется классами, которые предоставляют большое количество событий для более эффективной обработки памяти, выделяя пространство для поля поддержки событий только тогда, когда это необходимо, а не при объявлении события. Поэтому все события для главной формы хранятся там.
Я ожидал, что дочерняя форма отслеживала, когда ее родительская форма может быть закрыта (это обычный вариант использования), и она не отписывалась от событий FormClosing
или FormClosed
, когда он получил это событие. Однако это только предположение. Для подтверждения посмотрите на реализацию дочерней формы и найдите все случаи, когда она подписывается на события из родительской формы, а затем убедитесь, что есть соответствующая отписка от этих событий.
Обновление
Обнаруженный вами обработчик меню, который не был удален, вполне может быть корнем проблемы, которую вы видите. Попробуйте добавить вызов удаления и посмотрите, устранит ли это утечку.
Есть еще один объект, который ссылается на объект, который должен быть удален ГХ с помощью четверификатора. Смысл: есть еще один объект, который все еще подписан на событие ликвидированного объекта.
Вы можете решить эту проблему, отписавшись от события (удалить четвёрки из события), когда вы хотите утилизировать этот объект.