Возможно ли иметь постоянную утечку памяти, если не удалось утилизировать? - PullRequest
1 голос
/ 08 ноября 2019

Я знаю, что всегда полезно обернуть каждый IDisposible объект using. Но возможно ли создать постоянную утечку памяти, как с ++, если я не смог это сделать? (под постоянным я подразумеваю время жизни приложения)

Я знаю, что GC будет трудно работать с COM и собственными ресурсами, но давайте предположим, что я использую только управляемый код. Нет COM, нет небезопасных только встроенных пакетов и управляемого кода. Есть ли какие-либо IDisposible, которые GC не сможет собрать даже после того, как переменная выйдет из области видимости?

Ответы [ 2 ]

1 голос
/ 08 ноября 2019

Да. Когда GC собирает объект, тогда запускается finalizer объекта. В большинстве реализаций IDisposable, IDisposable.Dispose() вызывается из финализатора, что означает, что объект будет удален при сборке мусора.

Однако иногда это не так. Например, многие объекты в библиотеке SharpDX не располагаются в их финализаторах, поэтому, если вы не располагаете ими, то собственные объекты, которые они представляют (в данном случае графические ресурсы), не будут очищеныи вы закончите с утечкой памяти. Это на самом деле источник этой проблемы У меня было некоторое время назад.

Редактировать: я не видел, чтобы вы не упомянули неуправляемые ресурсы. В этом случае нет. Весь код C #, который не зависит от неуправляемого кода, должен зависеть от BCL, который нелегко создает утечки памяти.

0 голосов
/ 08 ноября 2019

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

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

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

...