Диспетчер рабочих наборов принимает решения об усечении каких-либо рабочих наборов, исходя из объема доступной памяти. Если памяти достаточно, он подсчитывает, сколько страниц можно при необходимости изъять из рабочего набора. Как только такая необходимость появится, он уменьшит рабочие наборы, размер которых превышает минимальный. Диспетчер рабочих наборов динамически регулирует частоту проверки рабочих наборов и оптимальным образом упорядочивает список процессов – кандидатов на усечение рабочего набора. Например, первыми проверяются процессы со множеством страниц, к которым не было недавних обращений; часто простаивающие процессы большего размера являются более вероятными кандидатами, чем реже простаивающие процессы меньшего размера; процессы активного приложения рассматриваются в последнюю очередь и т. д.
Определив, что размеры рабочих наборов процессов превышают минимальные значения, диспетчер ищет страницы, которые можно удалить из их рабочих наборов и сделать доступными для использования в других целях. Если свободной памяти по-прежнему не хватает, диспетчер продолжает удалять страницы из рабочих наборов процессов, пока в системе не появится минимальное количество свободных страниц.
B однопроцессорных системах Windows 2000 и всех системах Windows XP или Windows Server 2003 диспетчер рабочих наборов старается удалять страницы, к которым не было обращений в последнее время. Такие страницы обнаруживаются проверкой битового флага Accessed в аппаратном РТЕ. Если этот флаг сброшен, страница считается устаревшей, и соответствующий счетчик увеличивается на 1, показывая, что с момента последнего сканирования данного рабочего набора к этой странице не было обращений. Впоследствии возраст страниц учитывается при поиске кандидатов на удаление из рабочего набора.
Если битовый флаг Accessed в аппаратном PTE установлен, диспетчер рабочих наборов сбрасывает его и проверяет следующую страницу рабочего набора. Таким образом, если при следующем сканировании битовый флаг Accessed окажется сброшенным, диспетчер будет знать, что со времени последнего сканирования к этой странице не было обращений. Сканирование списка рабочего набора продолжается до удаления нужного числа страниц или до возврата к начальной точке. (B следующий раз сканирование начнется там, где оно остановилось в прошлый раз.)
ЭКСПЕРИМЕНТ: просмотр размеров рабочих наборов процессов
C этой целью можно использовать счетчики в оснастке Performance (Производительность), перечисленные в следующей таблице.
Несколько других утилит для просмотра сведений о процессах (Task Manager, Pview и Pviewer) тоже показывают размеры рабочих наборов.
Суммарный размер рабочих наборов всех процессов можно получить, выбрав процесс _Total в оснастке Performance. Этот несуществующий процесс просто представляет суммарные значения счетчиков всех процессов, выполняемых в системе в данный момент. Однако суммарный размер не соответствует истине, так как при подсчете размера рабочего набора процесса учитываются его разделяемые страницы. B итоге страница, разделяемая двумя или более процессами, засчитывается в размер рабочего набора каждого из таких процессов.
ЭКСПЕРИМЕНТ: просмотр списка рабочего набора
Элементы рабочего набора можно увидеть с помощью команды
Заметьте, что одни элементы списка рабочего набора представляют собой страницы, содержащие таблицы страниц (элементы с адресами выше OxCOOOOOOO), другие – страницы системных DLL (в диапазоне
Расширение и усечение рабочего набора выполняется в контексте системного потока диспетчера настройки баланса (balance set manager) (процедура
Диспетчер настройки баланса ждет на двух объектах «событие»: один из них освобождается по сигналу таймера, срабатывающего раз в секунду, а другой представляет собой внутреннее событие диспетчера рабочих наборов, освобождаемое диспетчером памяти, когда возникает необходимость в изменении рабочих наборов. Например, если в системе слишком часто генерируются ошибки страниц или список свободных страниц слишком мал, диспетчер памяти пробуждает диспетчер настройки баланса, а тот вызывает диспетчер рабочих наборов для усечения таких наборов. Если свободной памяти много, диспетчер рабочих наборов разрешает процессам, часто вызывающим ошибки страниц, постепенно увеличивать размеры своих рабочих наборов, подкачивая в память страницы, при обращении к которым возникали ошибки. Однако рабочие наборы расширяются лишь по мере необходимости.
Диспетчер настройки баланса, пробуждаемый в результате срабатывания таймера, выполняет следующие операции.
1. При каждом четвертом пробуждении из-за срабатывания таймера освобождает событие, которое активизирует системный поток, выполняющий процедуру
2. Проверяет ассоциативные списки и регулирует глубину их вложения, если это необходимо (для ускорения доступа, снижения нагрузки на пул и уменьшения его фрагментации).
3. Ищет потоки, чей приоритет может быть повышен из-за нехватки процессорного времени (см. раздел «Динамическое повышение приоритета при нехватке процессорного времени» главы 6).
4. Вызывает диспетчер рабочих наборов (имеющий собственные внутренние счетчики, которые определяют, когда и насколько агрессивно следует проводить усечение рабочих наборов).
Подсистема загрузки-выгрузки пробуждается и планировщиком, если стек ядра потока, подлежащего выполнению, или весь процесс выгружен в страничный файл. Подсистема загрузки-выгрузки ищет потоки, которые находились в состоянии ожидания в течение 7 секунд fWindows 2000) или 15 секунд (Windows XP и Windows Server 2003). Если такой поток есть, подсистема загрузки-выгрузки переводит его стек ядра в переходное состояние (перемещая соответствующие страницы в список модифицированных или простаивающих страниц). Здесь действует принцип «если поток столько времени ждал, подождет и еще». Когда из памяти удаляется стек ядра последнего потока процесса, этот процесс помечается как полностью выгруженный. Вот почему у долго простаивавших процессов (например, у Winlogon после вашего входа в систему) может быть нулевой размер рабочих наборов.