Моя чистая библиотека DotNET работает как плагин в неуправляемом настольном приложении. Я получал устойчивое (хотя низко) поток отчетов о катастрофическом отказе, которые, кажется, указывают на проблему с дескрипторами GDI (шрифты в сообщениях об ошибках и т.д. возвращаются к системному шрифту, дисплей всех видов средств управления ломаются, серьезный катастрофический отказ вскоре после).
Мои Формы имеют немного средств управления, но я делаю много GDI + тянущий в Пользовательских элементах управления. Что состоит в том, чтобы сказать хороший путь, сколько дескрипторов я использую или даже пропускаю?
Спасибо, David
В прошлом мне приходилось сталкиваться с подобной проблемой. Чтобы проверить, сколько объектов GDI выделяет ваше приложение, вы можете использовать бесплатный инструмент под названием GDIUsage.
В моем случае приложение аварийно завершало работу, потому что выделяло более 10.000 объектов GDI, что является жестким ограничением в Windows XP. Возможно, стоит разобраться в этом.
Я писал об этой проблеме здесь:
http://megakemp.com/2009/02/25/gdi-memory-leak-in-windows-forms/
Если вы еще не делаете этого, убедитесь, что вы вызываете IDisposable.Dispose для всех используемых вами объектов рисования GDI+. Обычно это делается с помощью конструкции C# using
, например:
using(Brush brush = ...)
{
...
}
Инструменты статического анализа кода, такие как FxCop или версия, встроенная в Team System редакции Visual Studio, могут помочь обнаружить случаи, когда вы не вызываете Dispose.
Невызов Dispose в этом случае является потенциальной утечкой хэндла, поскольку хэндл не будет возвращен до тех пор, пока сборщик мусора не сочтет нужным.
Кроме монитора производительности, вы можете попробовать старый добрый диспетчер задач.
Проверьте вкладку Process и нажмите View
> Select Columns...
и проверьте объекты GDI.
Это легко увидеть из TaskMgr.exe, вкладка Processes. View + Select Columns, поставьте галочку GDI Objects.
Ваше описание действительно соответствует утечке хэндла. Этого не должно происходить в управляемой программе, финализатор должен позаботиться о том, чтобы вы не забыли вызвать Dispose(). Если только вы не используете много места в куче собранного мусора. Это также может быть неуправляемое приложение, которое очень часто пропускает хэндлы.
Взгляните на GDIView (это бесплатное программное обеспечение):
GDIView - это уникальный инструмент, который отображает список дескрипторов GDI (кистей, перьев, шрифтов, растровых изображений и др.) , открытых каждым процессом. Он отображает общее количество для каждого типа дескриптора GDI , а также подробную информацию о каждом дескрипторе. Этот инструмент может быть полезен разработчикам, которым необходимо отслеживать утечку ресурсов GDI в их программном обеспечении.
(источник: nirsoft.net )
Обратите внимание , что автоматическое обновление отключено по умолчанию, но его можно включить и настроить для определенных интервалов: Параметры -> Авто Обновить -> Каждые [N] секунд
GDIObj, бесплатную утилиту, предоставленную Фэн Юанем в качестве образца программы для его книги, Windows Graphics Programming: Win32 GDI и DirectDraw может оказаться полезной.
В отличие от диспетчера задач, он предоставляет графы дальнейшей разбивки различных типов GDI-ручек, включая DC, Region, Bitmap, Palette, Font, Brush и т.д.
(Однако он предоставляет только информацию о количестве, в то время как GDIView предоставляет более подробную информацию о дескрипторах)
.