Читаем без скачивания 2.Внутреннее устройство Windows (гл. 5-7) - Марк Руссинович
Шрифт:
Интервал:
Закладка:
Диспетчер куч предоставляет несколько средств, помогающих обнаруживать ошибки.
• Enable tail checking (включить проверку концевой части блока) B конец каждого блока помещается сигнатура, проверяемая при его освобождении. Если эта сигнатура полностью или частично уничтожается из-за переполнения буфера, куча сообщает о соответствующей ошибке.
• Enable free checking (включить проверку свободных блоков) Свободный блок заполняется определенным шаблоном, который проверяется, когда диспетчеру куч нужен доступ к этому блоку. Если процесс продолжает записывать в блок после его освобождения, диспетчер куч обнаружит изменения в шаблоне и сообщит об ошибке.
• Parameter checking (проверка параметров) Проверка параметров, передаваемых функциям куч.
• Heap validation (проверка кучи) Вся куча проверяется при каждом обращении к ней.
• Heap tagging and stack traces support (поддержка меток и трассировки стека) Это средство поддерживает задание меток для выделяемой памяти и/или перехват трассировок стека пользовательского режима при обращениях к куче, что помогает локализовать причину той или иной ошибки.
Первые три средства включаются по умолчанию, если загрузчик обнаруживает, что процесс запущен под управлением отладчика. (Отладчик может переопределить такое поведение и выключить эти средства.) Средства отладки для куч могут быть заданы установкой различных отладочных флагов в заголовке образа через утилиту gflags (см. раздел «Глобальные флаги Windows» в главе 3) или командой !heap в любом стандартном отладчике Windows.
Включение средств отладки влияет на все кучи в процессе. Кроме того, включение любого средства отладки приводит к автоматическому отключению интерфейсного уровня и переходу на использование базового. Интерфейсный уровень также не применяется для нерасширяемых куч (из-за дополнительных издержек) или для куч, не допускающих сериализации.
PageheapТак как при проверке концевых частей блоков и шаблона свободных блоков могут обнаруживаться повреждения, произошедшие задолго до проявления собственно проблемы, предоставляется дополнительный инструмент отладки куч, pageheap, который переадресует все обращения к куче (или их часть) другомудиспетчеру куч. Pageheap является частью Windows Application Compatibility Toolkit, и его можно скачать с www.microsoft.com. Pageheap помещает выделенные блоки в конец страниц, поэтому при переполнении буфера возникнет нарушение доступа, что упростит выявление ошибочного кода. Блоки можно помещать и в начало страниц для обнаружения проблем, связанных с неполным использованием буферов (buffer underruns). (Такие ситуации — большая редкость.) Pageheap также позволяет защищать освобожденные страницы от любых видов доступа для выявления ссылок на блоки после их освобождения.
Заметьте, что применение pageheap может привести к нехватке адресного пространства, так как выделение даже очень малых блоков памяти сопряжено с существенными издержками. Также может ухудшиться производительность из-за увеличения количества ссылок на обнуленные страницы, потери локальности и частых вызовов для проверки структур кучи. Чтобы уменьшить негативное влияние на производительность, pageheap можно использовать только для блоков определенных размеров, конкретных диапазонов адресов и т. д.
ПРИМЕЧАНИЕ Подробнее о pageheap см. статью 286470 в Microsoft Knowledge Base (http://support.microsoft.com).
Address Windowing ExtensionsХотя 32-разрядные версии Windows поддерживают до 128 Гб физической памяти (см. таблицу 2–4 в главе 2), размер виртуального адресного пространства любого 32-разрядного пользовательского процесса по умолчанию равен 2 Гб (при указании загрузочных параметров /3GB и /USERVA в Boot.ini этот размер составляет 3 Гб). Чтобы 32-разрядный процесс мог получить доступ к большему объему физической памяти, Windows поддерживает набор функций под общим названием Address Windowing Extensions (AWE). Так, в системе под управлением Windows 2000 Advanced Server с 8 Гб физической памяти серверное приложение базы данных может с помощью AWE использовать под кэш базы данных до 6 Гб памяти.
Выделение и использование памяти через функции AWE осуществляется в три этапа.
1. Выделение физической памяти.
2. Создание региона виртуального адресного пространства — окна, на которое будут проецироваться представления физической памяти.
3. Проецирование на окно представлений физической памяти.
Для выделения физической памяти приложение вызывает Windows-функцию AllocateUserPhysicalPages. (Эта функция требует, чтобы у пользователя была привилегия Lock Pages In Memory.) Затем приложение обращается к Windows-функции VirtucriAlloc с флагом MEM_PHYSICAL, чтобы создать окно в закрытой части адресного пространства процесса, на которое проецируется (частично или полностью) ранее выделенная физическая память. Память, выделенная через AWE, может быть использована почти всеми функциями Windows API. (Например, функции Microsoft DirectX ее не поддерживают.)
Если приложение создает в своем адресном пространстве окно размером 256 Мб и выделяет 4 Гб физической памяти (в системе с объемом физической памяти более 4 Гб), то оно получает доступ к любой части физической памяти, проецируя ее на это окно через Wmdows-функции MapUserPhysicalPages или MapUserPhysicalPagesScatter. Размер физической памяти, единовременно доступный приложению при такой схеме выделения, определяется размером окна в виртуальном адресном пространстве. Ha рис. 7–6 показано AWE-ОKHO в адресном пространстве серверного приложения, на которое проецируется регион физической памяти, предварительно выделенный через AllocateUserPhysicalPages.
AWE-функции имеются во всех выпусках Windows и доступны независимо от объема физической памяти в системе. Однако AWE наиболее полезен в системах с объемом физической памяти не менее 2 Гб, поскольку тогда этот механизм — единственное средство для прямого использования более чем 2 Гб памяти 32-разрядным процессом. Еще одно его применение — защита. Так как AWE-память никогда не выгружается на диск, данные в этой памяти никогда не имеют копии в страничном файле, а значит, никто не сумеет просмотреть их, загрузив компьютер с помощью альтернативной операционной системы.
Теперь несколько слов об ограничениях, налагаемых на память, которая выделяется и проецируется с помощью AWE-функций.
• Страницы такой памяти нельзя разделять между процессами.
• Одну и ту же физическую страницу нельзя проецировать по более чем одному виртуальному адресу в рамках одного процесса.
• B более старых версиях Windows страницы такой памяти могут иметь единственный атрибут защиты — «для чтения и записи». B Windows Server
2003 Service Pack 1 и выше также поддерживаются атрибуты «нет доступа» и «только для чтения».
O структурах данных таблицы страниц, используемой для проецирования памяти в системах с более чем 4 Гб физической памяти, см. раздел «Phy-sical Address Extension (PAE)» далее в этой главе.
Системные пулы памятиПри инициализации системы диспетчер памяти создает два типа динамических пулов памяти, используемых компонентами режима ядра для выделения системной памяти.
• Пул неподкачиваемой памяти (nonpaged pool) Состоит из диапазонов системных виртуальных адресов, которые всегда присутствуют в физической памяти и доступны в любой момент (при любом IRQL и из контекста любого процесса) без генерации ошибок страниц. Одна из причин существования такого пула — невозможность обработки ошибок страниц при IRQL уровня «DPC/dispatch» и выше (см. главу 2).
• Пул подкачиваемой памяти (paged pool) Регион виртуальной памяти в системном пространстве, содержимое которого система может выгружать в страничный файл и загружать из него. Драйверы, не требующие доступа к памяти при IRQL уровня «DPC/dispatch» и выше, могут использовать память из этого пула. Он доступен из контекста любого процесса. Оба пула находятся в системном адресном пространстве и проецируются на виртуальное адресное пространство любого процесса (их начальные адреса в системной памяти перечислены в таблице 7–8). Исполнительная система предоставляет функции для выделения и освобождения памяти в этих пулах (см. описание функций, чьи имена начинаются c ExAllocatePool, в Windows DDK).
B однопроцессорных системах создается три пула подкачиваемой памяти, а в многопроцессорных — пять. Наличие нескольких подкачиваемых пулов уменьшает частоту блокировки системного кода при одновременных обращениях нескольких потоков к процедурам управления пулами. Начальный размер подкачиваемого и неподкачиваемого пулов зависит от объема физической памяти и может при необходимости расти до максимального значения, вычисляемого в период загрузки системы.