Часть полного текста документа:Виртуальная память в Microsoft Windows Здесь мы рассмотрим архитектуру памяти, применяемую в Microsoft Windows. Виртуальное адресное пространство процесса Каждому процессу выделяется собственное виртуальное адресное пространство. Для 32-разрядных процессов его размер составляет 4 Гб. Соответственно 32-битный указатель может быть любым числом от 0x00000000 до 0xFFFFFFFF. Всего, таким образом, указатель может принимать 4 294 967 296 значений, что как раз и перекрывает четырехгигабайтовый диапазон. Для 64-разрядных процессов размер адресного пространства равен 16 экзабайтам, поскольку 64-битный указатель может быть любым числом от 0x00000000 00000000 до 0xFFFFFFFF FFFFFFFF и принимать 18 446 744 073 709 551 616 значений, охватывая диапазон в 16 экзабайтов.Поскольку каждому процессу отводится закрытое адресное пространство, то, когда в процессе выполняется какой-нибудь поток, он получает доступ только к той памяти, которая принадлежит его процессу. Память, отведенная другим процессам, скрыта от этого потока и недоступна ему. В Windows 2000 память, принадлежащая собственно операционной системе, тоже скрыта от любого выполняемого потока. Иными словами, ни один поток не может случайно повредить ее данные.В Windows 2000, ни один поток не может получить доступ к памяти чужого процесса. Итак, адресное пространство процесса закрыто. Отсюда вытекает, что процесс А в своем адресном пространстве может хранить какую-то структуру данных по адресу 0x12345678, и одновременно у процесса В по тому же адресу - но уже в его адресном пространстве - может находиться совершенно иная структура данных. Обращаясь к памяти по адресу 0x12345678, потоки, выполняемые в процессе А, получают доступ к структуре данных процесса А, Но, когда по тому же адресу обращаются потоки, выполняемые в процессе В, они получают доступ к структуре данных процесса В. Иначе говоря, потоки процесса А не могут обратиться к структуре данных в адресном пространстве процесса В, и наоборот Как адресное пространство разбивается на разделы Виртуальное адресное пространство каждого процесса разбивается на разделы. Их размер и назначение в какой-то мере зависят от конкретного ядра Windows (таблица 13-1) Раздел 32-разрядная Windows 2000 (на х86 и Alpha) 32-разрядная Windows 2000 (на х86 с ключом /3GB) 64-разрядная Windows 2000 (на Alpha и А-64) Windows 98 Для выявления 0x00000000 0x00000000 0x00000000 00000000 0x00000000 нулевых указателей 0x0000FFFF 0x0000FFFF 0x00000000 0000FFFF 0x00000FFF Для совместимости с программами DOS и 16-разрядной Windows Hет Нет Нет 0x00001000 0x003FFFFF Для кода и данных 0x00010000 0x00010000 0x00000000 00010000 0x00400000 пользовательского режима 0x7FFEFFFF 0xBFFFFFFF 0x000003FF FFFEFFFF 0x7FFFFFFF Закрытый, 0x7FFF0000 0xBFFF0000 0x000003FF FFFF0000 Нет размером 64 Кб 0x7FFFFFFF 0xBFFFFFFF 0x000003FF FFFFFFFF Для общих MMF (файлов, проецируемых в память) Нет Нет Нет 0x80000000 0xBFFFFFFF Для кода и данных 0x800000000 0xC0000000 0x00000400 00000000 0xC0000000 режима ядра 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF FFFFFFFF 0xFFFFFFFF Таблица 13-1. Так адресное пространство процесса разбивается на разделы Раздел для выявления нулевых указателей (Windows 2000 и Windows 98) Этот раздел адресного пространства резервируется для того, чтобы программисты могли выявлять нулевые указатели. Любая попытка чтения или записи в память по этим адресам вызывает нарушение доступа. Довольно часто в программах, написанных на С/С++, отсутствует скрупулезная обработки ошибок. Например, в следующем фрагменте кода такой обработки вообще нет: int* pnSomeInteger = (int*) malloc(sizeof(int)); *pnSomeInteger = 5; При нехватке памяти malloc вернет NULL. ............ |