B этом примере использована х86-система под управлением Windows XP с параметром LargeSystemCache, равным 0; как видите, виртуальный размер кэша в такой системе составляет 0x20000 страниц. Поскольку на платформе x86 размер страниц равен 4 Кб, под виртуальный кэш выделено 512 Мб из 2-гигабайтного системного адресного пространства.
Размер рабочего набора кэша
Как уже упоминалось, одно из ключевых отличий архитектуры диспетчера кэша Windows от таковой в других операционных системах — делегирование управления физической памятью диспетчеру памяти. Ввиду этого размером кэша управляет уже имеющийся в операционной системе код, отвечающий за обработку расширения и усечения рабочего набора, а также за управление списками модифицированных и простаивающих страниц.
У системного кэша нет собственного рабочего набора — он использует единый системный набор, в который входят кэш данных, пул подкачиваемой памяти, а также подкачиваемый код Ntoskrnl и драйверов. Как упоминалось в главе 7, этот рабочий набор имеет внутреннее название рабочий набор системного кэша, но системный кэш является лишь одним из его элементов. Поэтому мы будем использовать термин «системный рабочий набор». Также в главе 7 мы обратили ваше внимание на то, что при присвоении параметру реестра LargeSystemCache значения 1 диспетчер памяти отдает предпочтение системному рабочему набору по сравнению с рабочими наборами процессов, выполняемых в системе.
Выяснить физический размер системного кэша, сравнить его с суммарным физическим размером системного рабочего набора, а также получить информацию об ошибках страниц для системного рабочего набора позволяют счетчики производительности или системные переменные, перечисленные в таблице 11-3.
ЭКСПЕРИМЕНТ: просмотр рабочего набора кэша
Как показано на листинге ниже, команда !filecacbe отладчика ядра выводит дамп информации о физической памяти, используемой кэшем, текущем и пиковом размерах рабочего набора, количестве действительных страниц, сопоставленных с представлениями, и, где это возможно, имена файлов, проецируемых на представления. (Драйверы файловых систем кэшируют метаданные с помощью безымянных файловых потоков.)
Физический размер кэша
Хотя системный рабочий набор включает объем физической памяти, проецируемой на представления в виртуальном адресном пространстве кэша, он не обязательно отражает общий объем файловых данных, кэшируемых в физической памяти. Между этими двумя значениями нередко бывают расхождения, потому что часть файловых данных может находиться в принадлежащем диспетчеру памяти списке простаивающих или модифицированных страниц.
Вспомните из главы 7, что при усечении рабочего набора или замене страниц диспетчер памяти может переместить измененные страницы из рабочего набора в список простаивающих или модифицированных страниц — в зависимости от того, куда должны быть записаны данные, содержащиеся на такой странице, перед ее повторным использованием — в страничный файл или в какой-то другой. Если бы у диспетчера памяти не было таких списков, то всякий раз, когда какой-нибудь процесс обращался бы к данным, ранее удаленным из его рабочего набора, диспетчеру памяти приходилось бы считывать их с диска. A так диспетчер памяти может просто вернуть нужную страницу в рабочий набор процесса (если она, конечно, присутствует в одном из этих списков). To есть списки служат кэшами данных из страничного файла, исполняемых образов или файлов данных. Значит, общий объем файловых данных, кэшируемых в системе, складывается не только из размера системного рабочего набора, но и из размеров списков простаивающих и модифицированных страниц.
Вот пример, иллюстрирующий, как диспетчер кэша способен привести к кэшированию в физической памяти гораздо большего объема файловых данных, чем может содержаться в системном рабочем наборе. Рассмотрим систему, выступающую в роли выделенного файл-сервера. B этой системе имеется 8 Гб физической памяти, и виртуальный размер кэша составляет 960 Мб (максимальный размер в х86-системах). Таким образом, предельный размер файловых данных, которые можно напрямую спроецировать в виртуальную память кэша, составляет 960 Мб. Клиентское приложение обращается к файловым данным на сервере через сеть. Драйвер файл-сервера (\Windows\System32\Drivers\Srv.sys) (см. главу 12) использует интерфейсы диспетчера кэша для чтения и записи файловых данных в интересах клиента. Если клиенты считывают несколько тысяч файлов, каждый размером по 1 Мб, диспетчеру кэша придется повторно использовать представления при проецировании 961-го файла. При последующих операциях чтения он будет отменять проецирование представлений для старых файлов и заново проецировать их для новых. Когда диспетчер кэша отменяет проецирование какого-либо представления, диспетчер памяти не отбрасывает файловые данные в рабочем наборе кэша, соответствующие этому представлению, а перемещает их в список простаивающих страниц. B отсутствие запросов на выделение физической памяти под любые другие задачи список простаивающих страниц может занимать почти всю физическую память за вычетом системного рабочего набора. Иначе говоря, практически все 8 Гб физической памяти сервера будут задействованы для кэширования файловых данных, как показано на рис. 11-6.
Рис. 11 -6. Пример использования почти всей физической памяти под файловый кэш
Поскольку общий объем кэшируемых файловых данных складывается из размеров системного рабочего набора, списка модифицированных страниц и списка простаивающих страниц, а эти размеры контролируются диспетчером памяти, в каком-то смысле его можно назвать истинным диспетчером кэша. Подсистема диспетчера кэша просто предоставляет удобные интерфейсы для доступа к файловым данным через диспетчер памяти и определяет политики опережающего чтения (read-ahead) и отложенной записи (write-behind), которые влияют на то, какие данные диспетчер памяти будет удерживать в физической памяти.
Для более точного отображения полного объема файловых данных, кэшируемых в системе, диспетчер задач и Process Explorer предоставляют параметр System Cache (Системный кэш), отражающий суммарный размер системного рабочего набора и списков простаивающих и модифицированных страниц. Пример для Process Explorer представлен на рис. 11-7.
Структуры данных кэша
Для отслеживания кэшируемых файлов диспетчер кэша использует следующие структуры данных.
• Каждый 256-килобайтный слот системного кэша описывается VACB.
• У каждого отдельно открытого кэшируемого файла есть закрытая карта кэша с информацией, применяемой для контроля опережающего чтения.
• Каждый кэшируемый файл имеет общую структуру карты кэша, которая указывает на слоты системного кэша, содержащие проецируемые представления файла.
Эти структуры и их взаимосвязи описываются в следующих разделах.
Общесистемные структуры данных кэша
Диспетчер кэша отслеживает состояние спроецированных на системный кэш представлений с помощью массива структур данных, называемых блоками управления виртуальными адресами (virtual address control blocks, VACB). При инициализации системы диспетчер кэша выделяет часть пула неподкачиваемой памяти под VACB, необходимые для описания системного кэша. Адрес массива VACB запоминается в переменной CcVacbs. Каждый VACB описывает одно 256-килобайтное представление в системном кэше (рис. 11-8). Структура VACB показана на рис. 11-9.