Приложение.NET внезапно испытывает резкий рост неуправляемой памяти

Я запускаю приложение, которое показывает некоторые очень специфические проблемы. Он работает нормально около 2,5 часов, затем внезапно начинает расти неуправляемая память и быстро расти. Примерно через полчаса приложение вылетает.

Приложение не использует неуправляемые библиотеки DLL. Это общение с внешним приложением. Он пишет с помощью сокета (используется через поток) и читает через поток WCF.

Я сделал это с помощью ANTS. Внезапное изменение в использовании неуправляемой памяти очень поразительно; он остается идеально ровным навсегда, затем внезапно начинает увеличиваться и продолжает делать это с постоянной скоростью, пока приложение не выйдет из строя. Ничто в управляемой памяти не кажется неуместным.

Учитывая, что я не намеренно использую неуправляемый код, трудно определить, откуда происходит утечка. ANTS не поможет. Трудно очистить код от проблем, когда он не увеличивается с самого начала (приложение все время бездействует, хотя оно и пингует свой сервер один раз в секунду через сокет с очень небольшим битом данных).

Чтобы повторить, приложение и сервер оба простаивают в течение этого времени; он работает в изолированной тестовой системе (как на сервере, так и на клиенте). Клиент - тот, который протекает.

2 ответа

Возможно, вы захотите использовать DebugDiag для мониторинга утечек памяти и предоставления информации о том, что было выделено, сколько и из каких стеков вызовов. Короче:

Вскоре после запуска (или перезапуска) процесса выполните следующие действия:

  1. Откройте DebugDiag.
  2. Отмена из мастера.
  3. Перейдите на вкладку Процессы.
  4. Щелкните правой кнопкой мыши по нужному процессу.
  5. Выберите "Монитор на утечки".
  6. Нажмите ОК.

После того, как процесс запущен некоторое время, и проблема с памятью очевидна:

  1. Перейти к DebugDiag
  2. Если он еще не был открыт, отмените его из мастера.
  3. Перейдите на вкладку Процессы.
  4. Щелкните правой кнопкой мыши по тому же процессу, что и часть № 1.
  5. Выберите Create Full Userdump.
  6. Запишите местоположение свалки.

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

Как только у вас есть свалка:

  1. Перейти к DebugDiag.
  2. Перейдите на вкладку "Расширенный анализ".
  3. Выберите скрипт "MemoryAnalysis.asp" вверху.
  4. Нажмите "Добавить файлы данных" внизу и выберите созданный ранее дамп.
  5. Нажмите "Начать анализ" и просмотрите результаты.

Получив эту информацию, вы сможете определить, откуда происходит выделение памяти, и, надеюсь, причину ваших проблем.

Вы можете найти больше информации на следующих ресурсах:

В конце концов мы нашли проблему. Оказалось, что у нас было сокетное соединение между ними, и во время фазы ожидания мы отправляли пакет KeepAlive, чтобы предотвратить автоматическое отключение слушателя. Однако после некоторого времени простоя, в течение некоторого времени ожидания с WCF сокет закрывался на стороне сервера.

Таким образом, в основном каждый раз, когда запускается DispatchTimer, пакет keep-alive будет записываться в сокет, но, очевидно, он будет блокироваться. Это не помешает следующему DispatchTimer сделать то же самое. Хотя казалось, что это нечто большее, эти маленькие пакеты быстро накапливались и поглощали всю неуправляемую память, я полагаю, что буфер для сокета (я полагаю, мы использовали NetworkStream для соединения). С несколькими изменениями в логике проблема исчезла.

Спасибо за все вклад, хотя, это было высоко оценено!

Другие вопросы по тегам