Вы уже должны немного представлять что такое пулы системной памяти. В этой статье обратим на них более пристальное внимание.
Пулы системной памяти
Когда система только загружается, диспетчер памяти создает два пула памяти, с динамически изменяемым размером:
- не выгружаемый пул — постоянно находится в оперативной памяти;
- выгружаемый пул — может выгружаться и снова подгружаться в память.
Эти пулы используются компонентами ядра.
Система при старте выделяет необходимый минимум для пулов, а затем позволяет им расти по необходимости, но у пулов есть лимиты.
Узнать лимит пулов для вашей системы можно используя «Process Explorer«, нужно открыть View / System Information и перейти на вкладку «Memory«:
- Paged Linmit (лимит выгружаемого пула) — примерно 16 ТБ.
- Nonpaged Limit (лимит не выгружаемого пула) — примерно 16 ГБ.
Знакомство с утилитой Poolmon
Для анализа пулов можно использовать программу Poolmon (но придется установить WDK Tools). Также доступны разные счетчики производительности.
Запустить утилиту можно так:
>"C:\Program Files (x86)\Windows Kits\10\Tools\x64\poolmon.exe"
Вот так выглядит окно Poolmon:
Клавиша «?» во время выполнения Poolmon вызывает экран со справочной информацией:
Чтобы выйти из справки нажмите «Esc«.
Клавишей «p» можно переключаться на режимы отображения:
- оба пула,
- только выгружаемый,
- только не выгружаемый.
Например, клавишей «p» настройте чтобы выводился только не выгружаемый пул, затем нажмете клавишу «D» для сортировки по столбцу Diff (разность), так вы узнаете, какие структуры наиболее многочисленны в не выгружаемом пуле.
За описаниями тегов пулов, используемых Windows, обращайтесь к файлу Pooltag.txt в подкаталоге Triage каталога, в котором размещается инструментарий отладки для Windows (C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\triage). Также информацию по тегам можно получить утилитой string, показанной чуть ниже.
Столбцы Poolmon:
- Tag — тег указывает на драйвер который использует пул памяти;
- Type — тип пула (выгружаемый или не выгружаемый);
- Allocs — количество всех операций выделения (в скобках изменение с момента последнее обновления программы);
- Diff — разность между количеством выделений и освобождений памяти;
- Bytes — общее количество байтов, потребляемых тегом(в скобках изменение с момента последнее обновления программы);
- Per Alloc — размер одного экземпляра данного тега в байтах.
Просмотр системных драйверов
Чтобы посмотреть какие системные драйверы загружены в системе можно выполнить следующее:
- Откройте меню Пуск и введите в поиске Msinfo32 (найдите программу «Сведения о системе«). А затем выполните её.
- Выберите узел Программная среда (Software Environment) / Системные драйверы (System Drivers).
Диагностика утечки памяти в пуле
Проведем диагностику утечки памяти в пулах. Утечка генерируется программой Notmyfault из пакета Sysinternals.
Выполните следующие действия:
- Запустите программу Notmyfault.exe для разрядности вашей ОС.
- Notmyfault.exe загружает драйвер устройства Myfault.sys и выводит диалоговое окно Not Му Fault с выбранной вкладкой Crash. Щелкните на вкладке Leak. Введите в поле Leak/second значение 1000 Кбайт.
- Щелкните на кнопке Leak Paged. Программа начинает отправлять драйверу Myfault запросы на выделение памяти из выгружаемого пула.
- Пока в пуле существует утечка, откройте Диспетчер задач, перейдите на вкладку «Быстродействие» (Performance) и выберите категорию «Память» (Memory). Обратите внимание: значение «Выгружаемый пул» (Paged Pool) постепенно растет.
- Чтобы определить, с каким тегом пулов связана утечка, запустите программу Poolmon и нажмите клавишу «В«, чтобы отсортировать информацию по количеству байтов.
- Клавишей Р настройте, чтобы в Poolmon отображался только выгружаемый пул. Обратите внимание: тег пула Leak поднимается в начало списка. Также Poolmon помечает изменения в выделенной памяти подсветкой изменяемых строк:
- Щелкните на кнопке Stop Paged, чтобы не исчерпать выгружаемый пул в вашей системе.
- Запустите программу Strings (из пакета Sysinternals), чтобы найти исполняемые файлы драйверов с тегом пула Leak.
>strings64.exe %SystemRoot%\system32\drivers\*.sys | findstr Leak
В результате поиска должен быть найден файл Myfault.sys, тем самым подтверждается что этот драйвер был виноват в утечке памяти.
Таким образом, если вы видите, что какой-то из пулов начал расти. То теперь вы знаете как отследить какой из драйверов потребляет слишком много памяти.