обнаружение утечек gdi / пользовательских обработчиков в winforms - PullRequest
4 голосов
/ 06 мая 2009

Я сделал отличное приложение winforms 2.0, и оно отлично работает, и клиенты по-прежнему довольны, но, к сожалению, я не могу решить одну проблему. Проблема в том, что после использования приложения в течение пары часов число дескрипторов пользователя gdi растет и растет, и, наконец, процесс не может выделить больше объектов и происходит сбой приложения ...

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

Мои вопросы:

  • есть ли "рекомендуемые практики" относительно добавления / удаления обычной системы управление формами во время выполнения (dgv / tlp)
  • как определить системные дескрипторы утечки - желательно с использованием визуального студия и своего рода бесплатный плагин (Профилировщик?) * * 1 010

Ответы [ 3 ]

5 голосов
/ 06 мая 2009

Обнаружение утечек графики и оконных ручек очень сложно. Что касается конкретной стратегии их поиска во время выполнения, я не могу ничего предложить (хотя я бы хотел услышать чью-то еще!).

Что касается их предотвращения, вот пара напоминаний:

  • Хотя финализатор класса Control будет вызывать Dispose(), это недетерминировано. Вы не гарантированы, что ЛЮБОЙ объект когда-либо будет завершен сборщиком мусора. Вероятно, что так и будет, но это не гарантия.
  • В соответствии с вышесказанным, формы являются исключением. Когда Form отображается НЕМОДАЛЬНЫМ способом (то есть через Show(), НЕ ShowDialog()), тогда, когда Form закрывается, это определенно вызовет Dispose(). Для форм, показанных через ShowDialog(), необходимо Dispose() вызывать вручную, чтобы детерминистически очистить дескриптор управления.
  • Помня об этих двух вещах, самое важное, что вы можете сделать, - это всегда вызывать Dispose() для любого объекта, который вы явно создаете и который реализует IDisposable. Это включает в себя Form s, Control s, Graphics объекты, даже графические вспомогательные классы, такие как Pen и Brush. Все эти классы реализуют IDisposable, и все они должны быть утилизированы, как только они вам больше не нужны.
  • Попробуйте кешировать ваши графические служебные классы, если вы их используете. Хотя Pen и Brush довольно легки для создания, они все же требуют ручек и должны быть утилизированы, когда вы закончите. Вместо того, чтобы создавать их постоянно, создайте менеджер кеша, который позволит вам передавать параметры, которые вы будете использовать в конструкторе для этих объектов, и поддерживать этот объект. Повторные вызовы с теми же параметрами должны по-прежнему использовать только один экземпляр. Затем вы можете периодически очищать кэш или в определенных местах приложения, если знаете, где они будут.

Следование этим указаниям значительно сократит - если не устранит - утечки вашей ручки.

1 голос
/ 06 мая 2009

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

0 голосов
/ 24 июня 2009

Исходный код для двух полезных инструментов отслеживания утечки GDI можно найти здесь: текст ссылки

Я успешно использовал его во многих проектах Visual Studio C ++. Я не уверен, что я тоже работаю с .NET.

...