2012-03-09 2 views
2

У меня есть служба C# .NET, работающая в процессе производства. Служба функционирует как TCP-сервер, на который клиенты регистрируются и делают запросы. При взгляде на диспетчер задач он, похоже, протекает около 10 МБ/день. Я, кажется, не замечаю их в dev (возможно, из-за гораздо меньшей активности трафика и клиента). При поиске я читал, что диспетчер задач может быть серьезно ошибочным, но я не уверен, насколько это точно или в каких обстоятельствах TM отображает неверную информацию.Устранение утечки памяти в службе .NET.

Для решения этой проблемы мне необходимо более внимательно следить за потреблением памяти. Проблема состоит в том, что утечка кажется, кажется, только в производстве, где развернутая служба была создана для Release. Кроме того, поскольку это служба, которая не может быть напрямую запущена VS с подключенным профилировщиком/отладкой, я не уверен, как лучше всего определить проблему с чем-то более точным, чем TM.

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

EDIT:

  • Я добавил системный монитор счетчики для рядовых байт службы (7MB начать), а также CLR ает во всех кучах (30MB начать)
  • Диспетчера задача говорит, что общая память составляет ~ 37 МБ, поэтому кажется, что это имеет смысл.
  • Первой частью этого является предоставление услуги в течение дня и проверка моих счетчиков снова.

Если мои личные байты становятся огромными, но CLR mem примерно статичен, это указывает на неуправляемую утечку. Если оба становятся огромными, то это управляемая утечка.

Спасибо, ребята.

+1

Почему бы не запустить сборку выпуска в тестовом режиме, чтобы увидеть, можете ли вы воспроизвести утечку? Это шаг 1. Идентификация утечки будет шагом 2 (с использованием профайлера памяти). – Oded

+0

Я сделал это. К сожалению, объем трафика на порядок выше на порядок ниже. Таким образом, утечка менее очевидна. – kmarks2

ответ

4

Ваша первая задача выяснить, если процесс утечки памяти. Вы можете сделать это с помощью perfmon, измеряющего частные байты http://www.goldstarsoftware.com/papers/CapturingVirtualBytesToALogFile.pdf

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

Если у вас действительно есть утечка памяти (и это не просто использование переменной памяти) - процесс будет завершен с отсутствием исключения из памяти после запуска на некоторое время.

+1

Awesome. Я играл с perfmon, но не добился большого прогресса в том, чтобы сделать его полезным. Это долгий путь. Благодарю. – kmarks2

+0

Я добавил счетчик личных байтов, а также CLR весь счетчик памяти кучи. За последний час частные увеличились с 7 до 8 МБ. Кажется, что куча CLR колеблется между 16 и 20 МБ. Странно, что это чистый проект C#. Там нет явного сортировки или COM-взаимодействия любого типа. Я предполагаю, что эти вещи могут происходить в фоновом режиме (поскольку все .NET TCP - это WinSock). – kmarks2

2

Для наблюдения за ним необходим один из нижеперечисленных MemoryProfilers;

http://www.jetbrains.com/profiler/

http://www.red-gate.com/products/dotnet-development/ants-memory-profiler/

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

+1

Но вы бы посоветовали использовать их для ** системы ** производства? – Oded

+1

Почему бы и нет. Лучше, чем «производственная система» с «утечкой памяти» – Zuuum

2

Следуйте этому руководству: http://blogs.msdn.com/b/tess/archive/2008/03/25/net-debugging-demos-lab-7-memory-leak.aspx

Он переходит именно то, что вы описываете, утечка памяти в производстве. Как уже упоминалось, вы должны сначала определить, происходит ли неуправляемый код или управляемый код с использованием perfmon и Private Bytes.

В общем, убедитесь, что для сетевых объектов вы их обертываете с помощью операторов, чтобы они были правильно расположены.

Рабочий процесс, который я часто использую для утечки управляемой памяти, - это запустить сервер на тестовой машине, нанести ему известное количество подключений (скажем, 123 456 соединений). Затем сделайте снимок памяти, перейдя в диспетчер задач и щелкнув правой кнопкой мыши по имени процесса и выбрав «создать дамп». Откройте этот дамп с помощью WinDBG и SOS и запустите команду! Dumpheap -stat. Ищите объекты, которые имеют кратное 123 456 экземпляров. Должны ли эти объекты оставаться в памяти? Если не запускать a! Gcroot в экземпляре этих объектов, чтобы найти, почему он все еще находится в памяти.

2
  1. Получить дамп памяти, когда он находится в состоянии утечки с помощью диспетчера задач, щелкните правой кнопкой мыши процесс и выберите файл создания дампа. Вы также можете использовать ProcDump, который дает вам больше возможностей.

  2. Используйте SOS-расширения в WinDebug или Visual Studio для проверки памяти.

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