GDI обрабатывает в приложении DotNET

Моя чистая библиотека DotNET работает как плагин в неуправляемом настольном приложении. Я получал устойчивое (хотя низко) поток отчетов о катастрофическом отказе, которые, кажется, указывают на проблему с дескрипторами GDI (шрифты в сообщениях об ошибках и т.д. возвращаются к системному шрифту, дисплей всех видов средств управления ломаются, серьезный катастрофический отказ вскоре после).

Мои Формы имеют немного средств управления, но я делаю много GDI + тянущий в Пользовательских элементах управления. Что состоит в том, чтобы сказать хороший путь, сколько дескрипторов я использую или даже пропускаю?

Спасибо, David

6
задан Ray Vega 7 April 2010 в 00:45
поделиться

6 ответов

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

В моем случае приложение аварийно завершало работу, потому что выделяло более 10.000 объектов GDI, что является жестким ограничением в Windows XP. Возможно, стоит разобраться в этом.

Я писал об этой проблеме здесь:
http://megakemp.com/2009/02/25/gdi-memory-leak-in-windows-forms/

2
ответ дан 8 December 2019 в 13:45
поделиться

Если вы еще не делаете этого, убедитесь, что вы вызываете IDisposable.Dispose для всех используемых вами объектов рисования GDI+. Обычно это делается с помощью конструкции C# using, например:

using(Brush brush = ...)
{
    ...
}

Инструменты статического анализа кода, такие как FxCop или версия, встроенная в Team System редакции Visual Studio, могут помочь обнаружить случаи, когда вы не вызываете Dispose.

Невызов Dispose в этом случае является потенциальной утечкой хэндла, поскольку хэндл не будет возвращен до тех пор, пока сборщик мусора не сочтет нужным.

1
ответ дан 8 December 2019 в 13:45
поделиться

Кроме монитора производительности, вы можете попробовать старый добрый диспетчер задач.

Проверьте вкладку Process и нажмите View > Select Columns... и проверьте объекты GDI.

3
ответ дан 8 December 2019 в 13:45
поделиться

Это легко увидеть из TaskMgr.exe, вкладка Processes. View + Select Columns, поставьте галочку GDI Objects.

Ваше описание действительно соответствует утечке хэндла. Этого не должно происходить в управляемой программе, финализатор должен позаботиться о том, чтобы вы не забыли вызвать Dispose(). Если только вы не используете много места в куче собранного мусора. Это также может быть неуправляемое приложение, которое очень часто пропускает хэндлы.

1
ответ дан 8 December 2019 в 13:45
поделиться

Взгляните на GDIView (это бесплатное программное обеспечение):

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

alt text
(источник: nirsoft.net )

Обратите внимание , что автоматическое обновление отключено по умолчанию, но его можно включить и настроить для определенных интервалов: Параметры -> Авто Обновить -> Каждые [N] секунд

4
ответ дан 8 December 2019 в 13:45
поделиться

GDIObj, бесплатную утилиту, предоставленную Фэн Юанем в качестве образца программы для его книги, Windows Graphics Programming: Win32 GDI и DirectDraw может оказаться полезной.

В отличие от диспетчера задач, он предоставляет графы дальнейшей разбивки различных типов GDI-ручек, включая DC, Region, Bitmap, Palette, Font, Brush и т.д.

(Однако он предоставляет только информацию о количестве, в то время как GDIView предоставляет более подробную информацию о дескрипторах)

.
1
ответ дан 8 December 2019 в 13:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: