Почему растет невыгружаемый пул памяти в Windows?

Почему растет невыгружаемый пул памяти в Windows?

На компьютерах и серверах Windows могут возникать проблемы с исчерпанием свободной памяти, вызванной утечкой некого системного драйвера, хранящего свои данные в невыгружаемом пуле памяти системы. Невыгружаемый пул памяти (Non-paged memory) – это данные в оперативной памяти компьютера, используемые ядром и драйверами операционной системой, которая никогда не выгружается на диск (в своп/ файл подкачки), т.е. всегда находится в физической RAM памяти.

Текущий размер невыгружаемого пула памяти можно увидеть в диспетчере задач Windows на вкладке Perfomance (Производительность) в разделе Memory (Память). На скриншоте ниже видно, что практически вся память на сервере занята, и большая часть ее относится к невыгружаемому пулу 4,2 Гб (Non-paged pool / Невыгружаемый пул). В нормальном состоянии размер невыгружаемого пула редко превышает 200-400 Мб. Большой размер невыгружаемого пула часто указывает на наличии утечки памяти в каком-то системном компоненте или драйвере.

Non-paged pool забил всю память компьютера

При утечке памяти в невыгружаемом пуле на сервере, в системном журнале событий появится события:

Event ID: 2019
Source: Srv
Description:
The server was unable to allocate from the system nonpaged pool because the pool was empty

В подавляющем большинстве случаев причиной такой утечки памяти является проблема со сторонними драйверами, установленными в Windows. Как правило, это сетевые драйвера. Обратите внимание, как ведет себя пул при скачивании больших файлов (скорее всего он при этом быстро растет).

Максимальный размер невыгружаемого пула в Windows:

  • Windows x64 до 128 Гб и не более 75% физической памяти
  • Windows x86 до 2 Гб и не более 75% RAM

Для очистки пула помогает только перезагрузка, и, если для домашнего компьютера это еще может быть приемлемо, то на круглосуточно работающем сервере желательно найти нормальное решение.

Установка последних версий драйверов сетевых адаптеров

Попробуйте скачать и установить последние версии драйверов ваших сетевых адаптеров с сайта производителя.

Если у вас в Windows включено автоматическое обновление драйверов, убедитесь не начались ли проблемы после установки новых драйверов. Попробуйте откатить версию драйвера на более старую и проверить, воспроизводится ли проблема. Если проблема решилась, отключите авто обновление драйверов.

Отключение драйвера мониторинга сетевой активности Windows

Достаточно часто причиной утечки памяти в невыгружаемый пул является несовместимость драйвера мониторинга сетевой активности (Network Data Usage — NDU, %WinDir%system32driversNdu.sys) с драйверами сетевого адаптера компьютера (чаще всего конфликтуют драйвера для сетевых карт Killer Network и MSI). Данный сервис можно отключить без особых потерь функционала Windows.

Службу можно остановить командной:

sc config NDU start= disabled

sc config NDU start= disabled

Либо через реестр:

  1. Откройте редактор реестра regedit.exe
  2. Перейдите в ветку HKEY_LOCAL_MACHINESYSTEMControlSet001ServicesNdu
  3. Измените значения параметра Start на 4.

отключение NDU - HKEY_LOCAL_MACHINESYSTEMControlSet001ServicesNdu

После внесения изменений нужно перезагрузить компьютер

Отключение роли Hyper-V

В некоторых случаях утечку памяти в невыгружаемый пул вызывает установленная роль Hyper-V. Если эта роль не нужна, рекомендуем отключить ее.

В Windows Server Hyper-V роль можно отключить командой:

Remove-WindowsFeature -Name Hyper-V

Команда для Windows 10:

Disable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-All

Поиск драйвера, вызвавшего утечку памяти с помощью Poolmon

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

Для этого нам понадобится консольная утилита Poolmoon.exe, входящая в комплект разработки Windows Driver Kit (WDK). Скачайте с сайта Microsoft и установите WDK для вашей версии Windows и запустите утилиту Poolmon.exe (в WDK для Windows 10 утилита находится в каталоге
C:Program Files (x86)Windows Kits10Tools
).

После запуска утилиты Poolman.exe нажмите клавиши P. Во втором столбце останутся теги процессов, которые используют невыгружаемую память (атрибут Nonp) Затем нажмите клавишу B, чтобы выполнить сортировку по столбцу Bytes.

Poolmoon - спсико тегов в невыгружаемом пуле памяти

В левом столбце указаны теги драйверов. Ваша задача определить файл драйвера, использующего этот тег. В нашем примере видно, что больше всего RAM в невыгружаемом пуле используют драйвера с тегами Nr22, ConT и smNp.

Вы должны проверить драйвера на наличие найденных тегов с помощью утилиты strings.exe (от Sysinternals), с помощью встроенной команды findstr или с помощью PowerShell.

Следующие команды должны найти файлы драйверов, связанные с найденными вами тегами. данными процессами можно командами:

findstr /m /l /s Nr22 %Systemroot%System32drivers*.sys
findstr /m /l /s ConT %Systemroot%System32drivers*.sys
findstr /m /l /s smNp %Systemroot%System32drivers*.sys

Также можно воспользоваться PowerShell:

Set-Location "C:WindowsSystem32drivers"
Select-String -Path *.sys -Pattern "Nr22" -CaseSensitive | Select-Object FileName -Unique
Select-String -Path *.sys -Pattern "Py28" -CaseSensitive | Select-Object FileName -Unique
Select-String -Path *.sys -Pattern "Ne40" -CaseSensitive | Select-Object FileName –Unique

Вы можете отобразить файлы драйверов непосредственно в poolmon.exe. Для этого убедитесь, что в каталоге утилиты находится файл pooltag.txt. Его можно скопировать из каталога установки WDK или найти в GitHub. Запустите утилиту:

Poolmon /g

poolmon показать имя драйвера использующего невыгружаемый пул

Обратите внимание, что имя драйвера теперь отображается в столбце Mapped_driver.

Если поиск не дал результатов, проверьте возможно утечка памяти вызвана не системным процессом. Запустите Task Manager, перейдите на вкладку Details, добавьте колонку NP Pool и найдите процессы с большим размером памяти в невыгружаемом пуле.

показывать размер невыгружаемого пула процессов в taskmanager Windows 10

Таким образом, мы получили список файлов драйверов, которые могут оказаться причиной проблемы. Теперь по именам файлов нужно определить, к каким драйверам и системным компонентам они относятся. Для этого можно воспользоваться утилитой sigcheck от Sysinternals.

sigcheck C:WindowsSystem32driversrdyboost.sys

Утилита возвращает имя драйвера, его свойства и информацию о версии.
sigcheck

Теперь можно попытаться удалить/обновить/переустановить проблемный драйвер или службу.

Если утечка памяти привела к BSOD, вы можете определить проблемный драйвер по файл дампа памяти.

  1. Загрузите дамп памяти в отладчик Windbg;
  2. Выполните команду:
    !vm
  3. Если значение NonPagedPool Usage больше чем Max, это говорит о том, что невыгружаемый пул исчерпан;
  4. Проверьте содержимое пула командой (результаты будут отсортированы по использованию невыгружаемого пула):
    !poolused 2
  5. После получение тега драйвера найдите файл с помощью findstr или strings как описано выше.

Данная инструкция применима как для Windows Server 2019/2016/2012R2, так и для клиентских Windows 10, 8.1.

Windows Server 2016
Почему растет невыгружаемый пул памяти в Windows?