Подводя итоги
А теперь попробуем осмыслить понятия адресных пространств, разделов, регионов, блоков и страниц как единое целое. Лучше всего начать с изучения карты виртуальной памяти, на которой изображены все регионы адресного пространства В пределах одного процесса. В качестве примера мы воспользуемся программой VMMap из главы 14. Чтобы в полной мере разобраться в адресном пространстве процесса, рассмотрим его в том виде, в каком оно формируется при запуске VMMap под управлением Windows 2000 на 32-разрядной процессорной платформе x86 Образец карты адресного пространства VMMap показан в таблице 13-2. На отличиях адресных пространств в Windows 2000 и Windows 98 я остановлюсь чуть позже.
Карта в таблице 13-2 показывает регионы, расположенные в адресном пространстве процесса. Каждому региону соответствует своя строка в таблице, а каждая строка состоит из шести полей.
В первом (крайнем слева) поле проставляется базовый адрес региона. Наверное, Вы заметили, что просмотр адресного пространства мы начали с региона по адресу 0x00000000 и закончили последним регионом используемого адресного простран-
ства, который начинается по адресу 0x7FFE0000. Все регионы непрерывны. Почти все базовые адреса занятых регионов начинаются со значений, кратных 64 Кб. Это связано с гранулярностью выделения памяти в адресном пространстве. А если Вы увидите какой-нибудь регион, начало которого не выровнено по значению, кратному 64 Кб, значит, он выделен кодом операционной системы для управления Вашим процессом.
Базовый адрес | Тип | Размер |
Блоки | Атрибут( ы) защиты | Описание | ||||||
00000000 | Free | 65536 | |||||||||
00010000 | Private | 4096 | 1 | -RW- | |||||||
00011000 | Free | G1440 | |||||||||
00020000 | Private | 4096 | 1 | -RW- | |||||||
000? 1000 | Free | 61440 | |||||||||
00030000 | Private | 1048576 | 3 | -HW- | Стек потока | ||||||
00130000 | Private | 1048576 | 2 | -RW- | |||||||
00230000 | Mapped | 65536 | 2 | -RW- | |||||||
00240000 | Mapped | 90112 | 1 | -R- | \Device\HarddiskVolume1\WINN7\system32\unicode.nls | ||||||
00256000 | Free | 40960 | |||||||||
00260000 | Mapped | 208896 | 1 | -R- | \Device\HarddiskVolume1\WINNT\system32\locale.nIs | ||||||
00293000 | Free | 53248 | |||||||||
002A0000 | Happed | 266240 | 1 | -R- | \Pevicc\HarddiskVolume1\WINNT\system32\sortkey.nls | ||||||
002E1000 | Free | 61440 | |||||||||
002F0000 | Mapped | 16384 | 1 | -R- | \Device\HarddiskVolume1\WINNT\system32\sorttbls.nls | ||||||
002F4000 | Free | 49152 | |||||||||
00300000 | Mapped | 819200 | 4 | ER- | |||||||
0003С8000 | Free | 229376 | |||||||||
00400000 | Image | 106496 | 5 | ERWC | С \CD\x86\Debug\14_VMMap.ехе | ||||||
0041A000 | Free | 24576 | |||||||||
00420000 | Mapped | 274432 | 1 | -R- | |||||||
00463000 | Free | 53248 | |||||||||
00470000 | Mapped | 3145728 | 2 | ER | |||||||
00770000 | Private | 4096 | 1 | -RW- | |||||||
00771000 | Free | 61440 | |||||||||
00780000 | Private | 4096 | 1 | -RW- | |||||||
00781000 | Free | 61440 | |||||||||
00790000 | Private | 65536 | 2 | -RW- | |||||||
007A0000 | Mapped | 8192 | 1 | -R- | \Device\HarddiskVolume1\WINNT\system32\ctype.nls | ||||||
007А2000 | Free | 1763893248 | |||||||||
699D0000 | Image | 45056 | 4 | ERWC | C:\WINNT\Systpm32\PSAPI dll | ||||||
6990В000 | Free | 238505984 | |||||||||
77D50000 | Image | 450560 | 4 | ERWC | С:\WINNT\system32\RPCRT4 DLL | ||||||
770ВЕ000 | Free | 8192 | |||||||||
770С0000 | Image | 344064 | 5 | ERWC | С:\WINNT\system32\ADVAPI32 dll | ||||||
77Е14000 | Free | 49152 | |||||||||
77E20000 | Image | 401408 | 4 | ERWC | C:\WINNT\system32\USER32 dll | ||||||
77Е82000 | Free | 57344 | |||||||||
77Е90000 | Image | 720896 | 5 | ERWC | С \WINNT\system32\KERNEL32.dll | ||||||
77F40000 | Image | 241664 | 4 | ERWC | С \WINKT\system32\GUI32 DLL | ||||||
77F7В000 | Free | 20480 | |||||||||
77FB0000 | image | 483328 | 5 | ERWC | С \WINNT\System32\ntdll.dll | ||||||
77FF000 | Free | 40960 | |||||||||
78000000 | Image | 290816 | 6 | bMWC | С \WINNT\system32\MSVCRI.dll | ||||||
78047000 | Free | 124424192 | |||||||||
7F6F0000 | Mapped | 1048576 | 2 | ER-- | |||||||
7F7F0000 | Free | 8126464 | |||||||||
7FFB0000 | Mapped | 147456 | 1 | -R-- | |||||||
7FFD4000 | Free | 40960 | |||||||||
7FFDE000 | Private | 4096 | 1 | ERW- | |||||||
7FFDF000 | Private | 4096 | 1 | ERW- | |||||||
7FFE0000 | Private | 65536 | 2 | -R-- |
Таблица 13-2. Образец карты адресного пространства процесса в Windows 2000 на 32-разрядном процессоре типа x86
Во втором поле показывается тип региона Free (свободный), Private (закрытый), Image (образ) или Mapped (проецируемый) Эти типы описаны в следующей таблице,
Тип | Описание |
Free | Этот диапазон виртуальных адресов не сопоставлен ни с каким типом физической памяти. Его адресное пространство не зарезервировано, приложение может зарезервировать регион по указанному базовому адресу или в любом месте в границах свободного региона |
Private | Этот диапазон виртуальных адресов сопоставлен со страничным файлом. |
Image | Этот диапазон виртуальных адресов изначально был сопоставлен с образом ЕХЕ- или DLL-файла, проецируемого в память, но теперь, возможно, уже нет Например, при записи в глобальную переменную из образа модуля механизм поддержки «копирования при записи» выделяет соответствующую страницу памяти из страничного файла, а не исходною образа файла |
Mapped | Этот диапазон виртуальных адресов изначально был сопоставлен с файлом данных, проецируемым в память, но теперь, возможно, уже нет. Например, файл данных мог быть спроецирован с использованием механизма поддержки «копирования при записи" Любые операции записи в этот файл приведут к тому, что соответствующие страницы памяти будут выделены из страничного файла, а не из исходного файла данных. |
В третьем поле сообщается размер региона в байтах. Например, система спроецировала образ User32.dll по адресу 0x77E20000. Когда она резервировала адресное
пространство для этого образа, ей понадобилось 401 408 байтов. Не забудьте, что в третьем поле всегда содержатся значения, кратные размеру страницы, характерному для данного процессора (4096 байтов для x86).
В четвертом поле показано количество блоков в зарезервированном регионе. Блок — это неразрывная группа страниц с одинаковыми атрибутами защиты, связанная с одним и тем же типом физической памяти (подробнее об этом мы поговорим в следующем разделе). Для свободных регионов это значение всегда равно 0, так как им не передается физическая память. (Поэтому в четвертой графе никаких данных для свободных регионов не приводится.) Но для занятых регионов это значение может колебаться в пределах от 1 до максимума (его вычисляют делением размера региона на размер страницы). Скажем, у региона, начинающегося с адреса Ox77E20000, размер — 401 408 байтов. Поскольку процесс выполняется на процессоре x86 (страницы памяти по 4096 байтов), максимальное количество блоков в этом регионе равно 98 (401 408/4096); ну а, судя по карте, в нем содержится 4 блока.
В пятом поле — атрибуты защиты региона. Здесь используются следующие сокращения: E = execute (исполнение), R = read (чтение), W= write (запись), С = copy-onwrite (копирование при записи). Если ни один из атрибутов в этой графе не указан, регион доступен без ограничений. Атрибуты защиты не присваиваются и свободным регионам. Кроме того, здесь Вы никогда не увидите флагов атрибутов защиты PAGE_ GUARD или PAGE_NOCACHE — они имеют смысл только для физической памяти, а не для зарезервированного адресного пространства. Атрибуты защиты присваиваются регионам только эффективности ради и всегда замещаются атрибутами защиты, присвоенными физической памяти.
В шестом (и последнем) поле кратко описывается содержимое текущего региона. Для свободных регионов оно всегда пустое, а для закрытых — обычно пустое, так как у VMMap нет возможности выяснить, зачем приложение зарезервировало данный закрытый регион. Однако VMMap все жe распознает назначение тех закрытых регионов, в которых содержатся стеки потоков. Стеки потоков выдают себя тем, что содержат блок физической памяти с флагом атрибутов защиты PAGE_GUARD. Если же стек полностью заполнен, такого блока у него нет, и тогда VMMap не в состоянии распознать стск потока.
Для регионов типа Image программе VMMap удается определить полное имя файла, проецируемого на этот регион. Она получает эту информацию с помощью ToolHelp-функций, о которых я упоминал в конце главы 4. В Windows 2000 программа VMMap может идентифицировать регионы, сопоставленные с файлами данных; для этого она вызывает функцию GetMappedFileName (ее нет в Windows 98).