Виртуальная память в Microsoft Windows
этой странице возможны любые операции, попытка записи приводит к тому, что процессу предоставляется "личная" копия данной страницыЗащита типа "копирование при записи"
Атрибуты защиты, перечисленные в предыдущей таблице, достаточно понятны, кроме двух последних: PAGE_WRITECOPY и PAGE_EXECUTE_WRITECOPY. Они предназначены специально для экономного расходования оперативной памяти и места в страничном файле. Windows поддерживает мехянизм, позволяющий двум и более процессам разделять один и тот же блок памяти. Например, если Вы запустите 10 экземпляров программы Notepad, все экземпляры будут совместно использовать одни и те же страницы с кодом и данными этой программы. И обычно никяких проблем не возникает — пока процессы ничего не записывают в общие блоки памяти. Только представьте, что творилось бы в системе, если потоки из разных процессов начали бы одновременно записывать в один и тот же блок памяти!
Чтобы предотвратить этот хаос, операционная система присваивает общему блоку памяти атрибут защиты "копирование при записи" (copy-on-write). Когда поток в одном процессе попытается что-нибудь записать в общий блок памяти, в дело тут же вступит система и проделает следующие операции:
Найдет свободную страницу в оперативной памяти. Заметьте, что при первом проецировании модуля на адресное пространство процесса эта страница будет скопирована на одну из страниц, выделенных в страничном файле. Поскольку система выделяет нужное пространство в страничном файле еще при первом проецировании модуля, сбои на этом этапе маловероятны.
Скопирует страницу с данными, которые поток пытается записать в общий блок памяти, на свободную страницу оперативной памяти, полученную на этапе 1. Последней присваивается атрибут защиты PAGE_WRITECOPY или PAGE_EXECUTE_WRITECOPY. Атрибут защиты и содержимое исходной страницы не меняются.
Отобразит виртуальный адрес этой страницы в процессе на новую страницу в оперативной памяти.
Когда система выполнит эти операции, процесс получит свою копию нужной страницы памяти.
Кроме того, при резервировании адресного пространства или передаче физической памяти через VirtualAlloc нельзя указывать атрибуты PAGE_WRITECOPY или PAGE_EXECUTE_WRITECOPY. Иначе вызов VirtualAlloc даст ошибку, a GetLastError вернет код ERROR_INVALID_PARAMETER. Дело в том, что эти два атрибута используются операционной системой, только когда она проецирует образы EXE- или DLL-файлов.
Базовый адрес | Тип | Размер | Блоки | Атрибут( ы) защиты | Описание |
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- | DeviceHarddiskVolume1WINN7system32unicode.nls |
00256000 | Free | 40960 | |||
00260000 | Mapped | 208896 | 1 | -R- | DeviceHarddiskVolume1WINNTsystem32locale.nIs |
00293000 | Free | 53248 | |||
002A0000 | Happed | 266240 | 1 | -R- | PeviccHarddiskVolume1WINNTsystem32sortkey.nls |
002E1000 | Free | 61440 | |||
002F0000 | Mapped | 16384 | 1 | -R- | DeviceHarddiskVolume1WINNTsystem32sorttbls.nls |
002F4000 | Free | 49152 | |||
00300000 | Mapped | 819200 | 4 | ER- | |
0003С8000 | Free | 229376 | |||
00400000 | Image | 106496 | 5 | ERWC | С CDx86Debug14_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- | DeviceHarddiskVolume1WINNTsystem32ctype.nls |
007А2000 | Free | 1763893248 | |||
699D0000 | Image | 45056 | 4 | ERWC | C:WINNTSystpm32PSAPI dll |
6990В000 | Free | 238505984 | |||
77D50000 | Image | 450560 | 4 | ERWC | С:WINNTsystem32RPCRT4 DLL |
770ВЕ000 | Free | 8192 | |||
770С0000 | Image | 344064 | 5 | ERWC | С:WINNTsystem32ADVAPI32 dll |
77Е14000 | Free | 49152 | |||
77E20000 | Image | 401408 | 4 | ERWC | C:WINNTsystem32USER32 dll |
77Е82000 | Free | 57344 | |||
77Е90000 | Image | 720896 | 5 | ERWC | С WINNTsystem32KERNEL32.dll |
77F40000 | Image | 241664 | 4 | ERWC | С WINKTsystem32GUI32 DLL |
77F7В000 | Free | 20480 | |||
77FB0000 | image | 483328 | 5 | ERWC | С WINNTSystem32ntdll.dll |
77FF000 | Free | 40960 | |||
78000000 | Image | 290816 | 6 | bMWC | С WINNTsystem32MSVCRI.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 — они имеют смысл только для физической памяти, а не для зарезервированного адресного пространства. Атрибуты защиты присваиваются регионам только эффективности ради и всегда замещаются атрибутами защиты, присвоенными физической памяти.
В шестом (и последнем) поле кратко описывается содержимое текущего региона. Для свободных регионов оно всегда пустое, а для закрытых — обычно пустое
Блоки внутри регионов
Попробуем увеличить детализацию адресного пространства (по сравнению с тем, что показано в таблице 13-2). Например, таблица 13-3 показывает ту же карту адресного пространства, но в другом "масштабе": по ней можно узнать, из каких блоков состоит каждый регион.
Базовый адрес | Тип | Размер | Блоки | Атрибут(ы) защиты | Описание |
00000000 | Free | 65536 | |||
00010000 | Private | 4096 | 1 | -RW- | |
00010000 | Private | 4096 | -RW- | ||
00011000 | Free | 61440 | |||
00020000 | Private | 4096 | 1 |