Подтвердить что ты не робот

WeakReferences не освобождаются во встроенной ОС

У меня странное поведение: Я получаю массивную утечку памяти при создании приложения WPF, которое работает на DLOG-терминале (Windows Embedded Standard SP1), который ведет себя отлично, если я запускаю его локально на обычном рабочем столе (Win7 prof.)

После многих неудачных попыток найти какую-либо проблему я поставил одну из них непосредственно рядом с моим монитором, установил ANTs MemoryProfiler и проработал один час тестового запуска, имитирующего пользовательские операции как на терминале, так и на моем компьютере разработки.

Результат состоит в том, что из-за некоторых странных причин встроенная система накапливает огромное количество объектов WeakReference и EffectiveValueEntry [].

Вот некоторые фотографии:

Разработка (ПК): enter image description here

enter image description here

И терминал: enter image description here

Просто взгляните на список классов... enter image description here

Кто-нибудь видел что-то подобное раньше и есть ли известные решения? Где я могу получить помощь?

(PS терминалы, где установлены изображения, подготовленные для .net4)

PPS: для близкого избирателя: я думаю, вопрос ясен: как я могу это исправить. Вы можете утверждать, что это проблема IT/OS и проблема программирования, но я думаю, что если я опубликую это в Ошибка сервера, она мгновенно закрывается вне темы...

UPDATE: Мне удалось найти большую часть проблемы, но она немного похожа на С++: Я использую класс элементов, похожий на ViewModel, для WPF-List, который предоставляет (среди прочих) ICommand (RelayCommand-pattern). Элементы, созданные на ходу в getter ViewModel-Property для представления, и кажется, что приложение /GC никогда не освобождало эти неиспользуемые команды - или подписки на их CanExecuteChanged - профайлер памяти показывает те, что "удерживаются слабая ссылка". Я изменил свой код для повторного использования этих моделей-элементов и Dispose/set для нулевого использования всех используемых свойств в их Dispose и использования этого также как очистка - как я уже сказал: чувствует себя как "удалить" в те старые дни С++. Вдобавок к этому я использую принудительный GC.Collect каждые 30 минут (да, я знаю - вы никогда не должны, но до сих пор у меня нет другого решения). С этой установкой приложения работают до 6 часов без проблем, но это не кажется правильным.

Я не могу понять, почему эти WeakReferences не востребованы, поскольку они находятся на моей настольной машине...

Любые мысли об этом? Пожалуйста!

UPDATE: Я все еще не в состоянии решить эту проблему, но вижу странное поведение: Если я использую PC-Anywhere для наблюдения за работой моего программного обеспечения на одном из терминалов, проблема исчезнет! Даже после запуска 8 часов. прямое программное обеспечение работает так, как должно - оно будет даже освобождать память (я помещаю небольшое отображение памяти на главный экран - скажем, я подключаюсь к терминалу и вижу, что память низкая - после ожидания нескольких минут память восстанавливается )

Итак, я думаю, что Devin (один ответ ниже) имеет преимущество в правильном направлении - что-то в программном обеспечении Remote-Control разблокирует поток финализатора или что-то, что блокирует GC - будь то симулированная клавиатура/мышь или что-то еще.

Любые мысли об этом?

4b9b3361

Ответ 1

У нас была (несколько) аналогичная проблема с моим приложением на планшете. Память будет исправлена ​​при запуске на рабочем столе, но не при запуске на планшете или другом устройстве, использующем панель ввода ПК. Проблема в том, что очередь финализации застревает. Финализатор COM-объектов ожидал выполнения чего-то в основном потоке, у которого не было цикла сообщений.

Решение заключалось в том, чтобы найти подходящее время для вызова Application.DoEvents(). У нас был метод, который будет называться прерывисто, и мы вызываем его с каждым 10-м звонком. Я не знаю, есть ли у вас такая же проблема, но, возможно, она может пролить свет.

РЕДАКТИРОВАТЬ: Мне нужно четко прояснить, что вызов DoEvents() - плохая идея. Он работает в этом случае, потому что в этом потоке нет никакого пользовательского интерфейса или что-либо еще, что может повлиять на эти события.

Ответ 2

Из скриншотов интересно видеть, что LOH растет одновременно с тем, что используемое пространство не сильно растет. Свободное пространство растет на LOH, что указывает на фрагментацию памяти из-за закрепленных объектов. Это похоже на застрявший поток финализатора, который предотвращает очистку управляемых объектов. Вы должны получить дамп памяти и проверить, в каком методе застряла нить финализатора. Вы можете сделать это довольно легко с помощью Windbg.