Архитектура памяти в MS Windows 200-2003. Организация «динамической» виртуальной памяти. Назначение и преимущество по сравнению с кучами ANSI C. Функции Win32 API.

Кучи (heaps) – это динамически распределяемые области данных. При порождении процесса ему предоставляется куча размером 1 Мбайт по умолчанию. Ее размер может изменяться параметром /HEAP при построении исполняемого модуля. Функции библиотеки времени исполнения компилятора CRT (malloc(), free() и т. д.) используют возможности куч.

Создание дополнительных «куч»:

- для повышения эффективности управления памятью;

- для уменьшения рабочего множества процесса ;

- для повышения эффективности работы многонитевых приложений;

- для “защиты” друг от друга различных структур данных;

- для быстрого освобождение всей памяти в куче.

Повышение эффективности управления памятью:

В системах со страничной организацией отсутствует проблема фрагментации физической памяти. Однако существует проблема фрагментации адресного пространства. В 4Gb адресном пространстве эта проблема не актуальна, но она имеет значение в 1Mb куче. Если элементы какой-либо структуры имеют один размер, а элементы другой структуры - другой размер, то полезно размещать эти структуры в разных кучах.

Уменьшение рабочего множества процесса:

В соответствии с принципом локальности, работа с разными структурами, чаще всего, происходит не одновременно. Границы элементов разных структур не выровнены на границу страницы. Обращение к элементам одной структуры вызывает подкачку всей страницы, а, значит и элементов другой структуры. Это увеличивает рабочее множество процесса.

Функции создания и использования «куч»:

HANDLE GetProcessHeap (VOID ) – для получения дескриптора кучи по умолчанию;

LPVOID HeapAlloc (HANDLE hHeap, DWORD dwFlags, DWORD dwSize) – для выделения из кучи блока памяти заданного размера и возвращения указателя;

LPVOID HeapReAlloc (HANDLE hHeap, DWORD dwFlags, LPVOID lpOldBlock, DWORD dwSize) – для изменения размера выделенного блока памяти с возможностью перемещения блока при необходимости;

BOOL HeapFree (HANDLE hHeap, DWORD dwFlags, LPVOID lpMem) – для освобождения выделенного блока памяти кучи.

Создание и уничтожение «кучи»:

HANDLE HeapCreate (

DWORD dwFlags,

DWORD dwInitialSize,

DWORD dwMaximumSize

);

BOOL HeapDestroy ( HANDLE hHeap);

Создание «кучи» - dwFlags:

HEAP_GENERATE_EXCEPTIONS – указывает системе на то, что в случае возникновения ошибки необходимо генерировать исключительную ситуацию. Это будет происходить во всех случаях, когда функция должна была бы возвратить значение null.

HEAP_NO_SERIALIZE – указывает, что пока выполняется текущий вызов HeapAlloc, к куче не будут происходить обращения из других потоков (т.е. программист сам берет на себя исключение ситуаций одновременных обращений).

HEAP_ZERO_MEMORY – указывает, что выделяемая память должна инициализироваться нулями. В противном случае память не обязательно инициализируется нулями.

Дополнительные возможности по управлению «кучами»

UINT HeapCompact (HANDLE hHeap, DWORD fdwFlags);

BOOL HeapLock (HANDLE hHeap);

BOOL HeapUnlock (HANDLE hHeap);

BOOL HeapWalk (HANDLE hHeap, PPROCESS_HEAP_ENTRY pHeapEntry);

Архитектура памяти в MS Windows 2000-2003. Проецируемые файлы, назначение и использование. Функции Win32 API.

Проецируемые файлы.

“Как и виртуальная память, проецируемые файлы позволяют резервировать регион адресного пространства и передавать ему физическую память. Различие между этими механизмами состоит в том, что в последнем случае физическая память не выделяется из системного страничного файла, а берется из файла, уже находящегося на диске. Как только файл спроецирован в память, к нему можно обращаться так, как будто он в нее целиком загружен.”

(Джеффри Рихтер. Windows для профессионалов.)

Файлы, проецируемые (отображаемые) в память, - это один из самых замечательных сервисов, которые Win32 предоставляет программисту. Его существование стирает для программиста грань между оперативной и дисковой памятью. Действительно, с точки зрения классической теории кэш, оперативная память и дисковое пространство - это три вида памяти, отличающиеся скоростью доступа и размером. Но если заботу о перемещении данных между кэшем и ОП берут на себя процессор и ОС, то перемещение данных между ОП и диском обычно выполняет прикладной процесс с использованием функций read() и write().

Win32 действует иначе: ОС берет на себя заботу о перемещении страниц адресного пространства процесса, находящихся в файле подкачки, причем в качестве файла подкачки может быть использован любой файл. Иначе говоря, страницы ВП любого процесса могут быть помечены как выгруженные, а в качестве места, куда они выгружены, может быть указан файл. Теперь при обращении к такой странице VMM произведет ее загрузку, используя стандартный механизм свопинга. Это позволяет работать с произвольным файлом как с регионом памяти.

Применение проецируемых файлов:

· Для запуска исполняемых файлов (EXE) и динамически связываемых библиотек (DLL).

· Для работы с файлами.

· Для одновременного использования одной области данных двумя процессами.

Запуск процесса:

1. Создать виртуальное адресное пространство процесса (размером 4Gb).

2. Резервировать в ВАП регион размером, достаточным для размещения исполняемого файла. Начальный адрес региона определяется в заголовке EXE-модуля. Обычно он равен 0x00400000.

3. Отобразить исполняемый файл на зарезервированное адресное пространство.

4. Таким же образом отобразить на ВАП процесса необходимые ему динамически связываемые библиотеки. Информация о необходимых библиотеках находится в заголовке EXE-модуля. Желательное расположение региона адресов описано внутри библиотеки.

Запуск EXE-файлов и DLL-библиотек

Архитектура памяти в MS Windows 200-2003. Организация «динамической» виртуальной памяти. Назначение и преимущество по сравнению с кучами ANSI C. Функции Win32 API. - student2.ru

Одновременное использование одной области данных двумя процессами

Архитектура памяти в MS Windows 200-2003. Организация «динамической» виртуальной памяти. Назначение и преимущество по сравнению с кучами ANSI C. Функции Win32 API. - student2.ru

Файлы данных, проецируемые в память

Проецирование файла данных в память:

1. Создается объект ядра “файл”. Для создания объекта “файл” используется функция CreateFile.

2. С помощью функции CreateFileMapping создается объект ядра “проецируемый файл”. При этом используется дескриптор файла, возвращенный функцией CreateFile.

3. Производится отображение объекта “проецируемый файл” или его части на адресное пространство процесса. Для этого применяется функция MapViewOfFile.

Завершение проецирования файла данных:

1. Выполняется открепление файла от адресного пространства процесса с помощью функции UnmapViewOfFile.

2. Выполняется уничтожение объектов “файл” и “проецируемый файл” с помощью функции CloseHandle.

Обеспечение когерентности:

Если один процесс меняет разделяемую область данных, то она меняется и для другого процесса. Операционная система обеспечивает когерентность разделяемой области данных для всех процессов. Но для обеспечения когерентности процессы должны работать с одним объектом “проецируемый файл”, а не с одним файлом.

Создание объекта «проецируемый файл»:

HANDLE CreateFileMapping (

HANDLE hFile, // дескриптор файла

LPSECURITY_ATTRIBUTES lpAttributes, // атрибуты защиты объекта

DWORD flProtect, // атрибуты защиты

DWORD dwMaximumSizeHigh, // старшее слово размера

DWORD dwMaximumSizeLow, // младшее слово размера

LPCTSTR lpName // имя объекта

);

Открытие объекта «проецируемый файл»:

HANDLE OpenFileMapping (

DWORD dwDesiredAccess, // режим доступа

BOOL bInheritHandle, // флажок наследования

LPCTSTR lpName // имя объекта

);

Функция проецирования области:

LPVOID MapViewOfFile (

HANDLE hFileMappingObject, // дескриптор объекта проецируемый файл

DWORD dwDesiredAccess, // режим доступа

DWORD dwFileOffsetHigh, // старшее DWORD смещения

DWORD dwFileOffsetLow, // младшее DWORD смещения

SIZE_T dwNumberOfBytesToMap // число отображаемых байтов

);

Функция проецирования области по определенному адресу:

LPVOID MapViewOfFileEx (

HANDLE hFileMappingObject, // дескриптор отображаемого объекта

DWORD dwDesiredAccess, // режим доступа

DWORD dwFileOffsetHigh, // старшее DWORD смещения

DWORD dwFileOffsetLow, // младшее DWORD смещения

SIZE_T dwNumberOfBytesToMap, // число отображаемых байтов

LPVOID lpBaseAddress // начальный адрес

);

Параметр dwDesiredAccess определяет требуемый режим доступа для страниц ВП, используемых для отображения:

· FILE_MAP_WRITE– доступ к операциям чтения-записи, проецируемый файл должен быть создан с защитой PAGE_READWRITE.

· FILE_MAP_READ – доступ только для чтения, проецируемый файл должен быть создан с защитой PAGE_READWRITE или PAGE_READONLY.

· FILE_MAP_ALL_ACCESS – то же самое, что и FILE_MAP_WRITE.

· FILE_MAP_COPY – копирование при доступе для записи, проецируемый файл должен создаваться с флажком защиты PAGE_WRITECOPY.

· FILE_MAP_EXECUTE – доступ к исполнению кода из отображаемой памяти , проецируемый файл должен быть создан с доступом PAGE_EXECUTE_READWRITE или PAGE_EXECUTE_READ.

Функция отмены проецирования области:

BOOL UnmapViewOfFile (

LPCVOID lpBaseAddress // начальный адрес

);

Создание и использование проецируемых файлов:

Общий механизм таков: один процесс создает объект “проецируемый файл” с помощью функции CreateFileMapping, передавая в параметре lpName имя объекта, которое является глобальным в системе. Другой процесс открывает уже созданный объект “проецируемый файл” по глобальному имени.Теперь два процесса могут совместно использовать объект “проецируемый файл”. При этом, при помощи функции MapViewOfFile каждый процесс проецирует этот объект на свое ВАП и используют эту часть адресного пространства как разделяемую область данных.

Наши рекомендации