2009-05-05 1 views
4

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

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

Моих вопросов:

  • есть какая-либо «рекомендуемая-практика» относительно добавления/удаления регулярной системы управления на формах во время выполнения (DGV/TLP)
  • как обнаружить систему ручка утечки - предпочтительно с использованием визуальной студии и вид бесплатного плагина

ответ

5

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

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

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

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

+0

Спасибо за ваши советы. Можете ли вы порекомендовать мне какие-либо инструменты/VS-плагины, которые могут помочь отслеживать/обнаруживать утечки в исходном коде? – tomo

+0

@tomo, Опять же, нет, я не знаю таких инструментов. Я немного разобрался, потому что у меня были проблемы, похожие на те, с которыми вы сталкиваетесь. Решая их, это привело меня к советам выше. –

+0

Формы, входящие в приложение MDI, также должны иметь функцию Dispose(), которая называется вручную: два условия, когда форма не расположена на закрытии, это когда (1) она является частью приложения с интерфейсом нескольких документов (MDI) и форма не видна; и (2) вы отобразили форму с помощью ShowDialog. В этих случаях вам нужно будет вручную вызвать Dispose, чтобы отметить все элементы формы для сбора мусора. –

1

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

+0

Да, я обнаружил проблему с помощью диспетчера задач, и причина этого вопроса заключается в том, как помочь исправить это. – tomo

+0

В этом случае я думаю, что сообщение Адама Робинсона должно помочь вам исправить эту проблему. –

0

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

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