Охота на утечки памяти в .NET Compact Framework (WinCE 5) - PullRequest
3 голосов
/ 17 ноября 2010

Я работаю с системой на основе транзакций на устройстве Windows CE в рамках Compact .NET Framework v3.5.Мы обнаружили, что по мере того, как выполняется все больше и больше транзакций, становится все меньше и меньше памяти.Очевидно, что какая-то утечка памяти.

После каждой транзакции мы берем два чтения памяти;один из ОС (вызов PInvoke), а другой из сборщика мусора.Мы обнаружили, что чтение ОС увеличивает использование памяти, в то время как чтение из ГХ остается относительно стабильным (около 1 МБ + +).

Приложение использует службы синхронизации Microsoft для хранения информации напару локальных баз данных (SQL Server Compact v3.5) и синхронизировать их с удаленным сервером.

Если бы это была Windows XP, я просто подключился бы к исполняемому файлу с WinDbg и проанализировал кучу, чтобы увидетьесли я создаю объекты, которые никогда не получают GC'd.Тем не менее, я даже не знаю, является ли проблема управляемой кучей.

Так что этот вопрос состоит из двух частей:

1) Каковы вероятные виновники утечки памяти таким образом вуправляемое приложение (DataAdapters, Streams и т. д.)?

2) Какие инструменты / методы отладки помогут мне отследить точную проблему?

Я знаю, что это не так уж и много,но на данном этапе у меня не так много информации, кроме этой.

Спасибо!

Ответы [ 2 ]

3 голосов
/ 17 ноября 2010

Есть два способа атаковать это. Во-первых, посмотреть на управляемые объекты и их время жизни. Вы можете использовать Remote Performance Monitor (RPM) для просмотра снимков кучи ГХ и сравнения их.

Вы можете использовать CLR Profiler , чтобы проверить дерево вызовов и увидеть, откуда поступают эти объекты.

Эти два инструмента обычно позволяют находить проблемы с управляемым кодом.

Теперь важно отметить, что вы говорите, что GC не сообщает о каком-либо росте, что говорит мне, что куча GC в порядке, и эти инструменты вряд ли найдут много в этом конкретном случае. Тем не менее, я выложил инструменты, потому что они могут помочь вам (или кому-то еще, читающему это) в будущем.

В вашем случае это звучит так, как будто у вас есть собственная утечка. Вы не сказали, какой тип памяти протекает - физический или виртуальный, - но почти наверняка что-то делает исходное распределение, которое не освобождается. SQL Compact - это мое предположение, основанное на том, что вы сказали о своей архитектуре, поскольку движок реализован в собственном коде с управляемым слоем, расположенным поверх него.

Я также собираюсь предположить, что основная причина заключается в том, что у вас есть несколько небольших управляемых объектов (возможно, SqlCeTransaction или SqlCeCommand), которые по отдельности имеют небольшую управляемую площадь, но выполняют некоторое собственное распределение для вас, и эти объекты выживают. ,

Управляемые инструменты должны позволять вам находить большое или растущее число этих предметов и определять корень, который мешает GC убить их. Было бы хорошо, если бы вы вызывали Dispose для всех используемых вами объектов SqlCe.

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

0 голосов
/ 17 ноября 2010

Звучит так, будто вы где-то пропускаете EndInvoke?Или не закрывать свои связи?

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

...