2013-11-21 2 views
3

Я изучаю использование GC и памяти в нашем приложении и заметил, что у нас, похоже, остались тысячи выживших. К сожалению, только номер не говорит мне, есть ли у нас проблема. Однако мы видим общие проблемы с производительностью, и у нас есть высокая память и много времени в GC.Как я могу исследовать оставшуюся очередь очереди окончательной доработки

В идеале ничто из того, что у нас нет, должно войти в очередь финализации. Это ошибка, если это так. Есть ли способ или инструмент, который я могу использовать для проверки этого? Одно из предположений, которое я слышал, - это специальная сборка с финализаторами, которые регистрируются каждый раз, когда они выполняются, но это довольно много усилий и будет работать только с объектами, чьи типы у нас есть. Есть ли более простой способ?

И стоит ли расследовать оставшихся в живых до завершения? Если да, то как?

+0

Возможно, это не то, что вы ищете; но когда я писал плагин для CRM для синхронизации с Outlook, он всегда ел много памяти (со временем). В итоге я разложил приложение на два - один для «общения с Outlook», а другой для «UI stuff»; часть «связь с внешним видом» была запущена в отдельном домене приложения - ничто не может выжить. Домен приложения не загружается :) –

ответ

5

Использование WinDbg с Psscor2 или Psscor4 удлинение (в зависимости версия, используемая вами приложение). К сожалению, пока нет версии для .NET 4.5. После настройки среды отладки (установки WinDbg и копирования в папку Psscor) создайте свалку процесса. Вы можете сделать это легко, например, с помощью инструмента Procdump:

procdump -ma <PID> 

Затем свалка нагрузки с помощью меню Файл -> Открыть Давка вариант самосвала. Нагрузка соответствующая версия Psscor:

.load psscor4 

Затем выполнить команду загрузки символов с серверов Microsoft (если это необходимо), убедитесь, что у вас есть подключение к интернету:

!symfix 

И теперь вы должны иметь доступ на много очень интересную команду (ищите !help, чтобы перечислить их).Чтобы увидеть финализации очереди:

!finalizequeue 

Там у вас будет список объектов, как:

7aa143e0  166  20,584 System.Diagnostics.PerformanceCounter 
79b5f6c8  543  21,720 System.Reflection.Emit.DynamicResolver 
673893a8  953  22,872 System.Web.HttpResponseUnmanagedBufferElement 

Это может помочь вам много. Но вы также можете осмотреть эти объекты (!do 7aa143e0), найти ссылки (!gcroot <address>) и т. Д.

+0

Отлично - это выглядит очень полезно. Как узнать, когда сбрасывать процесс? Могу ли я, например? в windbg положить условный разрыв в очереди, которая смотрит на длину? Или мне просто нужно сделать обоснованное предположение, основанное на GC perf counters и т. Д.? – Rob

+0

Вы можете настроить procdump для создания дампа при пороге определенного счетчика производительности. –

0

И стоит ли расследовать оставшиеся в живых до завершения?

Да, поскольку окончательная доработка оказывает влияние на производительность и ресурс.

Если да, то как?

Предлагаю проверку кода.

Есть ли у ваших типов финализаторы? Если да, то это правильно реализовано? Вам нужен только финализатор, если вы напрямую управляете неуправляемым ресурсом. И если у вас есть финализатор, вы должны реализовать IDisposable и использовать детерминированную очистку. Выполнение этого гарантирует, что ваши финализаторы никогда не будут вызваны. Вызов GC.SuppressFinalize(this) в методе Dispose гарантирует, что экземпляр не завершен, поскольку он уже был удален.

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

Смежные вопросы