Реферат: Виртуальная память в Microsoft Windows

Виртуальная память в Microsoft Windows

Зздесь мырассмотрим архитектуру памяти, применяемую в Microsoft Windows.

<span Arial",«sans-serif»">Виртуальное адресное пространство процесса

Каждому процессувыделяется собственное виртуальное адресное пространство. Для 32-разрядныхпроцессов его размер составляет 4 Гб. Соответственно 32-битный указатель можетбыть любым числом от 0x00000000 до 0xFFFFFFFF. Всего, таким образом, указательможет принимать 4 294 967 296 значений, что как раз и перекрываетчетырехгигабайтовый диапазон. Для 64-разрядных процессов размер адресногопространства равен 16 экзабайтам, поскольку 64-битный указатель может бытьлюбым числом от 0x00000000 00000000 до 0xFFFFFFFF FFFFFFFF и принимать 18 446744 073 709 551 616 значений, охватывая диапазон в 16 экзабайтов.Посколькукаждому процессу отводится закрытое адресное пространство, то, когда в процессевыполняется какой-нибудь поток, он получает доступ только к той памяти, котораяпринадлежит его процессу. Память, отведенная другим процессам, скрыта от этогопотока и недоступна ему. В Windows 2000 память, принадлежащая собственнооперационной системе, тоже скрыта от любого выполняемого потока. Иными словами,ни один поток не может случайно повредить ее данные.В Windows 2000, ни одинпоток не может получить доступ к памяти чужого процесса. Итак, адресноепространство процесса закрыто. Отсюда вытекает, что процесс А в своем адресномпространстве может хранить какую-то структуру данных по адресу 0x12345678, иодновременно у процесса В по тому же адресу — но уже в его адресномпространстве — может находиться совершенно иная структура данных. Обращаясь кпамяти по адресу 0x12345678, потоки, выполняемые в процессе А, получают доступк структуре данных процесса А, Но, когда по тому же адресу обращаются потоки,выполняемые в процессе В, они получают доступ к структуре данных процесса В.Иначе говоря, потоки процесса А не могут обратиться к структуре данных вадресном пространстве процесса В, и наоборот

<span Arial",«sans-serif»">Как адресное пространство разбивается наразделы

Виртуальноеадресное пространство каждого процесса разбивается на разделы. Их размер иназначение в какой-то мере зависят от конкретного ядра 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

<span Arial",«sans-serif»">Таблица13-1. Так адресное пространство процесса разбивается на разделы

<span Arial",«sans-serif»">Раздел для выявления нулевыхуказателей (Windows 2000 и Windows 98)

Этот разделадресного пространства резервируется для того, чтобы программисты могливыявлять нулевые указатели. Любая попытка чтения или записи в память по этимадресам вызывает нарушение доступа. Довольно часто в программах, написанных наС/С++, отсутствует скрупулезная обработки ошибок. Например, в следующемфрагменте кода такой обработки вообще нет:

<span Courier New"">int* pnSomeInteger= (int*) malloc(sizeof(int));
*pnSomeInteger = 5;

    

                                                                                                                                 При нехватке памяти malloc вернет NULL. Ho код не учитывает этувозможность и при ошибке обратится к памяти по адресу 0x00000000 А посколькуэтот раздел адресного пространства заблокирован, возникнет нарушение доступа иданный процесс завершится Эта особенность помогает программистам находить«жучков* в своих приложениях. В Windows 2000 программыдля MS-DOS и 16-разрядной Windows выполняются в собственных адресныхпространствах; 32-разрядные приложения повлиять на них не могут.

<span Arial»,«sans-serif»">Раздел для кода и данныхпользовательского режима (Windows 2000 и Windows 98)

В этом разделерасполагается закрытая (неразделяемая) часть адресного пространства процесса.Ни один процесс не может получить доступ к данным другого процесса, размещеннымв этом разделе. Основной объем данных, принадлежащих процессу, хранится именноздесь (это касается всех приложений) Поэтому приложения менее зависимы отвзаимных «капризов», и вся система функционирует устойчивее.                    В Windows 2000 сюдазагружаются все EXE- и DLL-модули В каждом процессе эти DLL можно загружать поразным адресам в пределах данного раздела, но так делается крайне редко. Наэтот же раздел отображаются все проецируемые в память файлы, доступные данномупроцессу. В 64-разрядной Windows 2000 ядро наконец получит то пространство, котороеему нужно на самом деле.

<span Arial",«sans-serif»">Увеличение разделадля кода и данных пользовательского режима до 3 Гб на процессорах x86 (толькоWindows 2000)

 Microsoft предусмотрела в версиях Windows 2000Advanced Server и Windows 2000 Data Center для процессоров x86 возможностьувеличения этого пространства до 3 Гб. Чтобы все процессы использовали разделдля кода и данных пользовательского режима размером 3 Гб, а раздел для кода иданных режима ядра — объемом 1 Гб, Вы должны добавить ключ /3GB к нужной записив системном файле Boot.ini. Как выглядит адресное пространство процесса в этомслучае, показано в графе «32-разрядная Windows 2000 (на x86 сключом /3GB)» таблицы 13-1.

<span Arial",«sans-serif»">Уменьшение разделадля кода и данных пользовательского режима до 2 Гб в 64-разрядной Windows 2000

Многиеразработчики захотят как можно быстрее перенести свои 32-разрндные приложения в64-разрядную среду. Но в исходном коде любых программ полно таких мест, гдепредполагается, что указатели являются 32-разрядными значениями. Простаяперекомпиляция исходного кода приведет к ошибочному усечению указателей инекорректному обращению к памяти. Однако, если бы система как-то гарантировала,что память никогда не будет выделяться по адресам выше 0x00000000 7FFFFFFF,приложение работало бы нормально. И усечение 64-разрядного адреса до32-разрядного, когда старшие 33 бита равны 0, не создало бы никаких проблем.Так вот, система дает такую гарантию при запуске приложения в «адреснойпесочнице» (address space sandbox), которая ограничивает полезное адресноепространство процесса до нижних 2 Гб. По умолчанию, когда Вы запускаете64-разрядное приложение, система резервирует все адресное пространствопользовательского режима, начиная с 0x0000000 80000000, что обеспечиваетвыделение памяти исключительно в нижних 2 Гб 64-разрядного адресногопространства. Это и есть «адресная песочница». Большинству приложенийэтого пространства более чем достаточно. А чтобы 64-разрядное приложение моглоадресоваться ко всему разделу пользовательского режима (объемом 4 Тб), егоследует скомпоновать с ключом /LARGEADDRESSAWARE.

<span Arial",«sans-serif»">Закрытый раздел размером 64 Кб (толькоWindows 2000)

Этот разделзаблокирован, и любая попытка обращения к нему приводит к нарушению доступаMicrosoft резервирует этот раздел специально, чтобы упростить внутреннююреализацию операционной системы. Вспомните, когда Бы передаете Windows-функцииадрес блока памяти и его размер, то она (функция), прежде чсм приступить кработе, проверяет, действителен ли данный блок. Допустим, Вы написали код:

<span Courier New"; mso-ansi-language:EN-US">BYTE bBuf[70000];                                                          DWORDdwNumBytesWritTen;

                                        <span Courier New";mso-ansi-language: EN-US">WriteProcessMemory(GetCurrentProcess(), (PVOID) 0x7FFEEE90, bBuf,sizeof(bBuf), &dwNumBytesWntten);

В случае функцийтипа WriteProcessMemory область памяти, в которую предполагается запись,проверяется кодом, работающим в режиме ядра, — только он имеет право обращатьсяк памяти, выделяемой под код и данные режима ядра (в 32-разрядных системах — поадресам выше 0x80000000). Если по этому адресу есть память, вызов WriteProcessMemory,показанный выше, благополучно запишет данные в ту область памяти, которая, поидее, доступна только коду, работающему в режиме ядра. Чтобы предотвратить этои в то же время ускорить проверку таких областей памяти, Microsoft предпочлазаблокировать данный раздел, и поэтому любая попытка чтения или записи в немвсегда вызывает нарушение доступа.

<span Arial",«sans-serif»">Раздел для кода иданных режима ядра (Windows 2000 и Windows 98)

В этот разделпомещается код операционной системы, в том числе драйверы устройств и коднизкоуровневого управления потоками, памятью, файловой системой, сетевойподдержкой. Все, что находится здесь, доступно любому процессу. В Windows 2000эти компоненты полностью защищены. Поток, который попытается обратиться поодному из адресов памяти в этом разделе, вызовет нарушение доступа, а этоприведет к тому, что система в конечном счете просто закроет его приложение.64-разрядной Windows 2000 раздел пользовательского режима (4 Тб) выглядитнепропорционально малым по сравнению с 16 777 212 Тб, отведенными под разделдля кода и данных режима ядра. Дело не в том, что ядру так уж необходимо всеэто виртуальное пространство, a просто 64-разрядное адресное пространствонастолько огромно, что его большая часть не задействована. Система разрешаетнашим программам использовать 4 Тб, а ядру — столько, сколько ему нужно. Ксчастью, какие-либо внутренние структуры данных для управлениянезадействованными частями раздела для кода и данных режима ядра не требуются.

<span Arial",«sans-serif»">Регионы в адресном пространстве

Адресноепространство, выделяемое процессу в момент создания, практически все свободно(незарезервировано). Поэтому, чтобы воспользоваться какой-нибудь его частью,нужно выделить в нем определенные регионы через функцию WirtualAlloc.Операциявыделения региона называется резервированием (reserving). Прирезервировании система обязательно выравнивает начало региона с учетом такназываемой гранулярности выделения памяти (allocation granularity).Последняя величина в принципе зависит от типа процессора, но для процессоров,рассматриваемых в книге (x86, 32- и 64-разрядных Alpha и IA-64), — онаодинакова и составляет 64 Кб.Резервируя регион в адресном пространстве, системаобеспечивает еще и кратность размера региона размеру страницы. Такназывается единица объема памяти, используемая системой при управлении памятью.Как и гранулярность выделения ресурсов, размер страницы зависит от типапроцессора В частности, для процессоров x86 он равен 4 Кб, а для Alpha(под управлением как 32-разрядной, так и 64-разядной Windows 2000) — 8 Кб.Иногда система сама резервирует некоторые регионы адресного пространства винтересах<span Arial",«sans-serif»">.

Если Вы попытаетесь зарезервировать регион размером 10Кб, система автоматически округлит заданное Вами значение до большей кратнойвеличины. А зто значит что на x86 будет выделен регион размером 12 Кб, ана Alpha — 16 Кб.Когда зарезервированный регион адресного пространствастановится не нужен, ею следует вернуть в общие ресурсы системы.Эта операция — освобождение(releasing) региона — осуществляется вызовом функции VirtualFree <span Arial",«sans-serif»">Передача региону физической памяти

Чтобызарезервированный регион адресного пространства можно было использовать, Выдолжны выделить физическую память и спроецировать её на этот регион. Такаяоперация называется передачей физической памяти (committing physicalstorage). Чтобы передать физическую память зарезервированному региону, Выобращаетесь все к той же функции VirtualAlloc.Передавая физическуюпамять регионам, нет нужды отводить ее целому региону. Можно, скажем,зарезервировать регион размером 64 Кб и нередать физическую память только еговторой и четвертой страницам. Когда физическая память, переданнаязарезервированному региону, больше не нужна, ее освобождают. Эта операция — возвратфизической памяти (decommitting physical storage) — выполняется вызовомфункции VirtualFree.         
Физическую память следует рассматривать как данные, хранимые в дисковом файлесо страничной структурой. Поэтому, когда приложение передает физическую памятькакому-нибудь региону адресного пространства (вызывая VirtualAttoc), онана самом деле выделяется из файла, размещенного на жестком диске. Размерстраничного файла в системе — главный фактор, определяющий количествофизической памяти, доступное приложениям. Реальный объем оперативной памятиимеет гораздо меньшее значение. Физическая память в страничном файле не хранится Windows 2000может использовать несколько страничных файлов, и, если они расположены наразных физических дисках, операционная система работает гораздо быстрее, посколькуспособна вести запись одновременно на нескольких дисках. Чтобы добавить илиудалить страничный файл, откройте в Control Panel апплет System, выберитевкладку Advanced и щелкните кнопку Performance Options. Нa экране появитсяследующее диалоговое окно.

<img src="/cache/referats/25425/image002.gif" v:shapes="_x0000_i1025">

Однако системадействует не так, иначе на загрузку и подготовку программы к запуску уходило быслишком много времени.При запуске приложения система открывает его исполняемыйфайл и определяет объем кода и данных. Затем резервирует регион адресногопространства и помечает, что физическая память, связанная с этим регионом, —сам ЕХЕ-файл, то есть вместо выделения какого-то пространства из страничногофайла система использует истинное содержимое, или образ (image) ЕХЕ-файлакак зарезервированный регион адресного пространства программы. Благодаря этомуприложение загружается очень быстро, а размер страничного файла удается заметноуменьшить. Образ исполняемого файла (т. e. EXE- или DLL-файл), размещенный нажестком диске и применяемый как физическая память для того или иного регионаадресного пространства, называется проецируемым в память файлом(memory-mapped file). При загрузке EXF, или DLL система автоматическирезервирует регион адресного пространства и проецирует на него образ файла.Помимо этого, система позволяет (с помощью набора функций) проецировать нарегион адресного пространства еще и файлы данных
Когда EXE- или DLL-файл загружается с дискеты Windows 2000 целиком копируют егов оперативную память, а в страничном файле выделяют такое пространство, чтобы внем мог уместиться образ загружаемого файла. Если нагрузка на оперативнуюпамять в системе невелика, EXE- или DLLфайл всегда запускается непосредственноиз оперативной памяти.Так сделано для корректной работы программ установки.Обычно программа установки запускается с первой дискеты, потом поочередновставляются следующие диски, на которых собственно и содержится устанавливаемоеприложение. Если системе понадобится какой-то фрагмент кода EXE- или DLLмодуляпрограммы установки, на текущей дискете его, конечно же, пет. Но, посколькусистема скопировала файл в оперативную память (и предусмотрела для него место встраничном файле), у нее не возникнет проблем с доступом к нужной части кодапрограммы установки

<span Arial",«sans-serif»">Атрибуты защитыОтдельным страницам физической памяти можноприсвоить свои атрибуты защиты показанные в следующей таблице.

           Атрибут защиты

Описание

PAGE_NOACCESS

Попытки чтения, записи или исполнения содержимого памяти на этой странице вызывают нарушение доступа

PAGE_READONLY

Попытки записи или исполнения содержимого памяти на этой странице вызывают нарушение доступа

PAGE_READWRITE

Попытки исполнения содержимого памяти на этой странице вызывают нарушение доступа

PAGE_EXECUTE

Попытки чтения или записи на этой странице вызывают нарушение доступа

PAGE_EXECUTE_READ

Попытки записи на этой странице вызывают нарушение доступа

PAGE_EXECUTE_READWRITE

На этой странице возможны любые операции

PAGE_WRITECOPY

Попытки исполнения содержимого памяти на этой странице выбывают нарушение доступа, попытка записи приводит к тому, что процессу предоставляется «личная» копия данной страницы

PAGE_EXECUTE_WRITECOPY

На этой странице возможны любые операции, попытка записи приводит к тому, что процессу предоставляется «личная» копия данной страницы

<span Arial",«sans-serif»">Защита типа «копирование призаписи»

Атрибуты защиты,перечисленные в предыдущей таблице, достаточно понятны, кроме двух последних: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

СWINNTSystem32tdll.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--

<span Arial",«sans-serif»">Таблица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 — они имеют смысл только для физическойпамяти, а не для зарезервированного адресного пространства. Атрибуты защитыприсваиваются регионам только эффективности ради и всегда замещаются атрибутамизащиты, присв

еще рефераты
Еще работы по программному обеспечению