Читаем 2.Внутреннее устройство Windows (гл. 5-7) полностью

B этом эксперименте вы устраните реальную утечку в пуле подкачиваемой памяти в своей системе, чтобы научиться на практике применять способы, описанные в предыдущем разделе. Утечка будет создаваться утилитой NotMyFault, которую можно скачать по ссылке wwwsysintemals.com/windowsinternalsshtmL (Заметьте, что эта утилита отсутствует в списке инструментов на основной странице Sysinternals.) После запуска NotMyFault.exe загружает драйвер устройства Myfault.sys и выводит такое диалоговое окно.

1. Щелкните кнопку Leak Pool. Это заставит NotMyFault посылать запросы драйверу устройства Myfault на выделение памяти из подкачиваемого пула. (He нажимайте кнопку Do Bug, иначе вы вызовете крах системы; предназначение этой кнопки описывается в главе 14, где демонстрируются различные типы аварийных ситуаций.) NotMyFault продолжит посылать запросы, пока вы не щелкнете кнопку Stop Leaking. Заметьте, что пул подкачиваемой памяти не освобождается даже при закрытии программы; в нем происходит постоянная утечка памяти до перезагрузки системы. Однако, поскольку утечка пула будет непродолжительной, это не должно вызвать никаких проблем в вашей системе.

2. Пока происходит утечка памяти в пуле, сначала откройте диспетчер задач и перейдите на вкладку Performance (Быстродействие). Вы увидите, как растет показатель Paged Pool (Выгружаемая память). To же самое можно увидеть в окне System Information утилиты Process Explorer. (Выберите Show и System Information.)

3. Чтобы определить метку пула, где происходит утечка, запустите Poolmon и нажмите клавишу b, чтобы сортировать по числу байтов. Дважды нажмите клавишу p для отображения в Poolmon только пула подкачиваемой памяти. Вы должны заметить, что пул с меткой «Leak» поднимается вверх по списку. (Poolmon выделяет строки, где происходят изменения.)

4. Теперь щелкните кнопку Stop Leaking, чтобы не истощить пул подкачиваемой памяти в своей системе.

5. Используя приемы, описанные в предыдущем разделе, запустите Strings (ее можно скачать с wwwsysinternals.com) для поиска двоичных файлов драйвера, содержащих метку пула «Leak»:

Strings \windows\system32\drivers\*.sys | findstr Leak

Эта команда должна указать на файл Myfault.sys.

Ассоциативные списки

Windows поддерживает механизм быстрого выделения памяти — ассоциативные списки (look-aside lists). Главное различие между пулом и ассоциативным списком в том, что из пула можно выделять блоки памяти различного размера, а из ассоциативного списка — только фиксированные. Хотя пулы обеспечивают более высокую гибкость, ассоциативные списки работают быстрее, так как не используют спин-блокировку и не заставляют систему подбирать подходящую область свободной памяти, в которой мог бы уместиться текущий выделяемый блок.

Функции ExInitializeNPagedLookasideList и ExInitializePagedLookasideList (документированные в DDK) позволяют компонентам исполнительной системы и драйверам устройств создавать ассоциативные списки, размеры которых кратны размерам наиболее часто используемых структур данных. Для минимизации издержек, связанных с синхронизацией в многопроцессорных системах, некоторые компоненты исполнительной системы, в том числе диспетчер ввода-вывода, диспетчер кэша и диспетчер объектов, создают отдельные для каждого процессора ассоциативные списки, из которых выделяется память под часто используемые структуры данных. Сама исполнительная система создает для каждого процессора универсальные ассоциативные списки подкачиваемой и неподкачиваемой памяти с гранулярностью выделения в 256 байтов или менее.

Если ассоциативный список пуст (как это бывает сразу после его создания), система должна выделить память из подкачиваемого или неподкачиваемого пула. Ho если в списке уже присутствует освобожденная структура, то занимаемая ею память выделяется очень быстро. (Список разрастается по мере возврата в него структур.) Процедуры выделения памяти из пула автоматически настраивают число освобожденных буферов, хранящихся в ассоциативном списке, в зависимости от частоты выделения памяти из этого списка драйвером или компонентом исполнительной системы. Чем чаще они выделяют память из списка, тем больше буферов в списке. Размер ассоциативных списков автоматически уменьшается, если память из них не выделяется. (Эта проверка выполняется раз в секунду, когда системный поток диспетчера настройки баланса пробуждается и вызывает функцию KiAdjustLookasideDepth.)

ЭКСПЕРИМЕНТ: просмотр системных ассоциативных списков

Содержимое и размер различных ассоциативных списков в системе можно просмотреть командой !lookaside отладчика ядра. Вот фрагмент вывода этой команды.

Утилита Driver Verifier
Перейти на страницу:

Похожие книги