Ликург
Заметки | Тех.книги | Худ.книги |

Метод обнаружения утечки памяти в ядре системы

Предистория:

В один прекрасный момент, свалились у меня сразу 3 рабочих терминала работающих в сетевом кластере. Анализ ядра с помощью poolmon показал, что утечка памяти возникает в модуле ядра Toke. Модуль то я определил, а почему в нём возникает утечка нет. Пришлось обратиться в платную поддержку MS. SoftwareAshurance дает возможность использовать 1 обращение по телефону, и неограниченное количество обращение по web. Обращался по web, по телефону все равно не решили бы. Вопрос решался 1 месяц. Дамп памяти передавался в российскую поддержку, затем в европейское отделение поддержки для анализа. Но анализ дампа ничего существенного не прояснил. Причину помог найти метод, предложенный европейской поддержкой. Оказалось, что виной всему сервис Windows AutoUpdate.

Метод определения утечки памяти в ядре системы (для тэгов Paged Pool):

1. Если сервер падает через определённые интервалы времени непрерывной работы, то скорее всего имеет место утечка памяти в ядре системы.

2. Мониторим ядро системы с помощью утилиты poolmon и определяем, имеет ли место постоянный рост занятой памяти в каких либо модулях ядра. Если утечка памяти происходит в Paged Pool тэге, то описанные ниже шаги, скорее всего позволят определить процесс вызывающий утечьку памяти (для NonPaged pool тэгов, метод не проверялся). Для мониторинга, можно через шедулер запускать с интервалом 1 час, команду poolmon.exe —b —n C:\poolmon.log (тэги выводятся в убывающем порядке по занимаемой ими памяти)

3. Мониторим процессы. Например, используя powershell:

Get-process | sort Handles —Descending | select —first 10

и определяем процесс с максимальным значением Handles, кол-во которых постоянно увеличивается.

4. Определяем сервис с которым связан процесс

tasklist /svc /FI "PID eq pid_процесса"

Даже если процессом является svchost, с помощью опции /svc мы узнаем список сервисов, которые он поддерживает (tasklist в русской версии сервера не работает, используйте от английского)

5. Если в проблемном экземпляре svchost.exe работает более одного сервиса, то разносим все эти сервисы по отдельным процессам. Cохраните, конфигурацию запуска сервиса:

sc query "имя_сервиса"  >> C:\services.txt

Переведите сервис в отдельный процесс svchost:

sc config "имя_сервиса" type= own

6. Возвращаемся к шагу 3 и определяем какой конкретно сервис вызывает утечку памяти. Если возможно, то гасим сервис и проверяем, освободилась ли память в ядре, используя poolmon.

7. Возвращаем режим запуска, измененных сервисов в исходное состояние.

sc config "Имя_сервиса" type= own|share|interact|kernel|filesys|rec|adapt

Необходимо выставить режим запуска, в соответствии с цифромыми значениями типа, сохраненными в C:\services.txt.

P.S.

Говорят ещё бывают аналогичные проблемы из-за разбухания реестра, но я с таким не сталкивался (см. http://www.osp.ru/win2000/2009/04/9048541/)