Интерфейс для управления памятью api
Работа приложений с виртуальной памятью Архитектура интерфейсов управления памятью Файлы, отображаемые в память Кучи Заключение Литература Virtual memory API Работа приложений с виртуальной памятью Архитектура интерфейсов управления памятью Составной частью ядра операционной системы является VMM.
Работа приложений с виртуальной памятью
Архитектура интерфейсов управления памятью
Составной частью ядра операционной системы является VMM. Приложения не могут получить к VMM прямой доступ, поэтому для управления памятью им предоставляются различные программные интерфейсы (API). Их архитектура приведена на рис. 1.
Одни интерфейсы построены на использовании других. Их взаимосвязь изображена на рисунке стрелками. Ниже приведен список интерфейсов с комментариями:
Virtual Memory API - набор функций, позволяющих приложению работать с виртуальным адресным пространством. Приложение может назначать физические страницы блоку адресов и освобождать их, а также устанавливать атрибуты защиты (см. врезку "Virtual Memory API");
Memory Mapped File API - набор функций использования файлов, отображаемых в память. Этот новый с точки зрения классического устройства ОС механизм предоставляется Win32 API для работы с файлами и взаимодействия процессов между собой;
Heap Memory API - набор функций для управления динамически распределяемыми областями памяти (кучами). Интерфейс построен с помощью Virtual Memory API;
Local, Global Memory API - программный интерфейс для работы с памятью, совместимый с 16-разрядной Windows (лучше его не использовать);
CRT Memory API - функции стандартной библиотеки времени исполнения языка Cи (C Run Time library).
Два последних набора функций в данной статье не рассматриваются.
Файлы, отображаемые в память
Файлы, отображаемые в память, - это один из самых замечательных сервисов, которые Win32 предоставляет программисту. Его существование стирает для программиста грань между оперативной и дисковой памятью. Действительно, с точки зрения классической теории кэш, оперативная память и дисковое пространство - это три вида памяти, отличающиеся скоростью доступа и размером. Но если заботу о перемещении данных между кэшем и оперативной памятью берут на себя процессор и операционная система, то перемещение данных между оперативной памятью и диском обычно выполняет прикладной процесс с использованием функций read() и write(). Win32 действует иначе: операционная система берет на себя заботу о перемещении страниц адресного пространства процесса, находящихся в файле подкачки, причем в качестве файла подкачки может быть использован любой файл. Иначе говоря, страницы виртуальной памяти любого процесса могут быть помечены как выгруженные, а в качестве места, куда они выгружены, может быть указан файл. Теперь при обращении к такой странице VMM произведет ее загрузку, используя стандартный механизм свопинга. Это позволяет работать с произвольным файлом как с регионом памяти. Данный механизм имеет в Win32 три применения:
- для запуска исполняемых файлов (EXE) и динамически связываемых библиотек (DLL);
- для работы с файлами;
- для совместного использования одной области данных двумя процессами.
Запуск на исполнение EXE-модуля происходит следующим образом. EXE-файл отображается на память, и при этом он не переписывается в файл подкачки. Просто элементы каталога и таблиц страниц настраиваются так, чтобы они указывали на EXE-файл, лежащий на диске. Затем передается управление на точку входа программы. При этом возникает исключение, обрабатывая которое стандартным образом, VMM загружает в память требуемую страницу, после чего программа начинает исполняться. Такой механизм существенно ускоряет процедуру запуска программ, так как загрузка страниц EXE-модуля происходит по мере необходимости. По сути, как ни парадоксально это звучит, программа сначала начинает исполняться, а потом загружается в память. Если программа записана на дискете, то перед началом исполнения она переписывается в файл подкачки. Именно поэтому на запуск программы с дискеты уходит значительно больше времени.
Рассмотрим механизм запуска программы на выполнение более подробно. При исполнении функции CreateProcess система обращается к VMM для выполнения следующих действий:
- Создать адресное пространство процесса.
- Зарезервировать в адресном пространстве процесса регион размером, достаточным для размещения исполняемого файла. Начальный адрес региона берется из заголовка EXE-модуля. Обычно он равен 0x00400000, но может быть изменен при построении файла заданием параметра /BASE компоновщика.
- Отобразить исполняемый файл на зарезервированное адресное пространство. Тем самым VMM распределяет физические страницы не из файла подкачки, а непосредственно из EXE-модуля.
- Отобразить в адресное пространство процесса необходимые ему динамически связываемые библиотеки. Информация о необходимых библиотеках читается из заголовка EXE-модуля. Желательное расположение региона адресов описано внутри отображаемых библиотек. Visual C++, например, по умолчанию устанавливает для своей библиотеки адрес 0x10000000. Этот адрес может тоже изменяться параметром /BASE компоновщика. Если при загрузке выясняется, что данный регион занят, то система попытается переместить библиотеку в другой регион адресов, согласуя это действие с настроечной информацией, содержащейся в DLL-модуле. Однако эта операция снижает эффективность системы, и кроме того, если при компоновке библиотеки настроечная информация удалена (параметр/FIXED), то загрузка становится вообще невозможной. Интересно, что все стандартные библиотеки Windows имеют фиксированный адрес загрузки, и каждая свой собственный.
При одновременном запуске нескольких приложений Win32 отображает один и тот же исполняемый файл и библиотеки на адресные пространства различных процессов. При этом возникает проблема независимого использования процессами статических переменных и областей данных. Кроме того, изменение данных исполняющейся программой не должно приводить к изменению EXE-файла. А ведь он является файлом подкачки и, значит, вытесняемые страницы должны попадать именно в него.
Мы уже обсуждали выше, что Win32, используя технологию lazy evaluation, откладывает решение этой проблемы на максимально возможный срок. Все страницы адресного пространства процесса, на которые отображен EXE-файл, получают атрибут защиты PAGE_WRITECOPY. При попытке записи в такую страницу возникает исключение нарушения защиты, и VMM копирует страницу для обратившегося процесса. В дальнейшем эта страница всегда будет выгружаться в файл подкачки. После копирования происходит повторный старт команды, вызвавшей исключение.
Отображение файла данных в адресное пространство процесса предоставляет мощный механизм работы с файлами - программа может работать с файлом, как с массивом ячеек памяти. Само проецирование файла в память выполняется в три этапа:
Для открепления файла от адресного пространства процесса используется функция UnmapViewOfFile(), а для уничтожения объектов "файл" и "отображаемый файл" - функция CloseHandle.
Общая методика работы с отображаемыми файлами такова:
Общая область данных может быть создана не только путем проецирования файла, но и путем проецирования части файла подкачки. Для этого в функцию CreateFileMapping() необходимо передать в качестве параметра не дескриптор ранее открытого файла, а константу 1. В этом случае необходимо задать размеры выделяемой области. Кроме того, в параметре lpName можно задать имя глобального объекта в системе. Если это имя задается в системе впервые, то процессу выделяется новая область данных, а если имя было уже задано, то именованная область данных предоставляется для совместного использования.
Если один процесс изменяет совместно используемую область данных, то она изменяется и для другого разделяющего ее процесса. Операционная система обеспечивает когерентность совместно используемой области данных для всех процессов, но для этого процессы должны работать с объектом "отображаемый файл", а не с самим файлом (рис. 2).
Кучи (heaps) - это динамически распределяемые области данных. При порождении процесса ему предоставляется куча размером 1 Мбайт по умолчанию. Ее размер может изменяться параметром /HEAP при построении исполняемого модуля. Функции библиотеки времени исполнения компилятора (malloc(), free() и т. д.) используют возможности куч.
Для работы с кучей предназначены следующие функции:
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) . Целесообразно использовать дополнительные кучи для защиты друг от друга различных структур данных, для повышения эффективности управления памятью и др. В системах со страничной организацией отсутствует проблема фрагментации физической памяти, однако существует проблема фрагментации адресного пространства. В 4-Гбайт адресном пространстве эта проблема не актуальна, но она имеет значение в куче размером 1 Мбайт. Если элементы какой-либо структуры имеют один размер, а элементы другой структуры - другой, то полезно размещать эти структуры в разных кучах. Кроме того, дополнительные кучи могут быть применены и для уменьшения рабочего множества процесса. В соответствии с принципом локальности работа с разными структурами чаще всего происходит не одновременно. Границы элементов разных структур не выравниваются на границу страницы, поэтому обращение к элементам одной структуры вызывает подкачку всей страницы, а значит, и элементов другой структуры. Это увеличивает рабочее множество процесса.
Заключение
Автор этих строк читает студентам лекции по курсу "Системное программное обеспечение". Саму дисциплину назвать новой никак нельзя. Теория организации вычислительного процесса сложилась уже к началу 70-х. Существовавшие в то время операционные системы давали массу примеров, позволяющих скрасить сухое академическое изложение. И сегодня по-прежнему излюбленной операционной системой для университетов является Unix, на которой воспитано не одно поколение студентов (в том числе и ваш покорный слуга). Никоим образом не умаляя достоинств Unix, можно с уверенностью утверждать, что Windows NT является ничуть не менее "классической" операционной системой в том смысле, что она доставляет примеры удачной реализации во всех разделах теории. Это не удивительно, ведь инженеры, создававшие Windows NT, были очень хорошо знакомы с такими системами, как Unix и Open VMS. При создании Windows NT было найдено много интереснейших технических решений, ряд из которых рассмотрен в данной статье, и название NT - New Technologies - можно считать вполне оправданным.
Андрей Федоров
- генеральный директор Digital Design Microsoft.
Литература
- Дейтел Г. Введение в операционные системы. М.: Мир.
- Донован Дж. Системное программирование. М.: Мир, 1975.
- Changes and Additions to the Alpha Architecture Definition. September 18, 1996.
- Randy Kath. The Virtual-Memory Manager in Windows NT. MSDN. Created: December 21, 1992.
- Pentium Pro Family Developer's Manual. Volume 3: Operating System Writer's Guide.
- How Windows NT Provides 4 Gigabytes of Memory. MSDN Knowledge Base. Article ID: Q99707. Creation Date: 06-JUN-1993. Revision Date: 17-JAN-1995.
- Рихтер Д. Windows для профессионалов. М.: изд. отд. "Русская редакция" ТОО Channel Trading Ltd., 1995.
- Working Set Size, Nonpaged Pool, and VirtualLock(). MSDN Knowledge Base. Article ID: Q108449. Creation Date: 12-DEC-1993. Revision Date: 02-NOV-1995.
Virtual memory API
Блок адресов в адресном пространстве процесса может находиться в одном из трех состояний:
- выделен (committed) - блоку адресов назначена физическая память либо часть файла подкачки;
- зарезервирован (reserved) - блок адресов помечен как занятый, но физическая память не распределена;
- свободен (free) - блок адресов не выделен и не зарезервирован.
Резервирование и выделение памяти производится блоками, начальные адреса которых должны быть выровнены на границу 64 Кбайт (округляется вниз), а размер кратен размеру страницы (округляется вверх). При выделении память обнуляется.
Для резервирования региона памяти в адресном пространстве процесса или ее выделения используется функция VirtualAlloc(), а для освобождения - функция VirtualFree():
Эта функция возвращает адрес выделенного региона, а в случае неудачи возвращает NULL. Параметры функции:
lpAddress - адрес, по которому надо зарезервировать или выделить память. Если этот параметр равен NULL, то система самостоятельно выбирает место в адресном пространстве процесса;
dwSize - размер выделяемого региона;
flAllocationType - тип распределения памяти;
flProtect - тип защиты доступа выделяемого региона:
PAGE_READONLY - допускается только чтение;
PAGE_READWRITE - допускается чтение и запись;
PAGE_EXECUTE - допускается только выполнение;
PAGE_EXECUTE_READ - допускается исполнение и чтение;
PAGE_EXECUTE_READWRITE - допускается выполнение, чтение и запись;
PAGE_GUARD - дополнительный флаг защиты, который комбинируется с другими флагами. При первом обращении к странице этот флаг сбрасывается и возникает исключение STATUS_GUARD_PAGE. Этот флаг используется для контроля размеров стека с возможностью его динамического расширения;
PAGE_NOCACHE - запрещает кэширование страниц. Может быть полезен при разработке драйверов устройств (например, данные в видеобуфер должны переписываться сразу, без кэширования).
Возвращает TRUE в случае успеха и FALSE в случае неудачи. Параметры:
lpAddress - адрес региона, который надо освободить;
dwSize - размер освобождаемого региона;
dwFreeType - тип освобождения.
Параметр flAllocationType может принимать следующие значения:
MEM_RESERVE - резервирует блок адресов без выделения памяти;
MEM_COMMIT - отображает ранее зарезервированный блок адресов на физическую память или файл подкачки, выделяя при этом память. Может комбинироваться с флагом MEM_RESERVE для одновременного резервирования и выделения;
MEM_TOP_DOWN - выделяет память по наибольшему возможному адресу. Имеет смысл только при lpAddress = NULL. В Windows 95 игнорируется.
MEM_DECOMMIT - освободить выделенную память;
MEM_RELEASE - освободить зарезервированный регион. При использовании этого флага параметр dwSize должен быть равен нулю.
Выделенные страницы можно заблокировать в памяти, т. е. запретить их вытеснение в файл подкачки. Такие страницы остаются в составе рабочего множества процесса до того момента, как будут разблокированы. Для этих целей служит пара функций VirtualLock() и VirtualUnlock(). Процессу не разрешается блокировать более 30 страниц. Для настройки рабочего множества процесса может использоваться и функция SetProcessWorkingSetSize() [8]. Формально она не входит в состав Virtual Memory API, но тесно с ним связана. Например, использование этой функции снимет барьер 30 страниц для функции VirtualLock().
Для изменения атрибутов защиты регионов используются функции VirtualProtect() и VirtualProtectEx(). Причем первая позволяет изменять атрибуты защиты в адресном пространстве текущего процесса, а вторая - произвольного.
Функции VirtualQuery() и VirtualQueryEx() позволяют определить статус указанного региона адресов.
Диспетчер управления памятью (VMM) является составной частью ядра операционной системы. Приложения не могут получить к нему прямой доступ. Для управления памятью прикладным программам предоставляются различные интерфейсы (API).
API Microsoft DirectX
API Microsoft DirectX – это набор программных интерфейсов, применяемых для решения различных задач: от программного управления аппаратным обеспечением компьютера до разработки мультимедийных приложений, использующих различные типы информации, и создания виртуальных миров.
Основная цель, которую преследовала фирма Microsoft, создавая интерфейс DirectX – превратить компьютеры, работающие под управлением операционной системы Windows, в универсальную платформу для приложений, богатых мультимедийными элементами: полноцветной графикой, видеофрагмен-
тами, трехмерной анимацией и стереозвуком. Встроенный непосредственно в ядро ОС Windows интерфейс DirectX является интегрированным сервисом
Windows 98 и Windows 2000, а также Microsoft Internet Explorer. Компоненты
DirectX могут быть также автоматически загружены на компьютер при установке современных игр и мультимедийных приложений, разработанных для ОС Windows 95. Для разработчиков DirectX представляет набор программных интерфейсов, использование которых позволяет решить две основные задачи.
Во-первых, DirectX превращает разработанные с его помощью приложения в программы, совместимые с любой версией Windows и работающие на любом компьютере, где установлена эта операционная система, независимо от типа используемого программного обеспечения. При этом подобные приложения максимально используют технические возможности компьютера, обеспечивая наивысшую производительность. Это достигается за счет сервиса, предоставляемого двумя основными компонентами DirectX: низкоуровневыми интерфейсами, входящими в состав DirectX Foundation, и высокоуровневыми интерфейсами, составляющими DirectX Media.
Во-вторых, DirectX предоставляет разработчикам возможность абстрагироваться от конкретного типа дисплейного адаптера, звуковой карты или 3Dускорителя и сосредоточиться на логике работы самой программы.
DirectX Foundation предоставляет в распоряжение разработчиков набор низкоуровневых программных интерфейсов, который обеспечивает эффективный доступ ко всем возможностям компьютера, работающего под управлением ОS Windows, реализованным на уровне аппаратного обеспечения – 3Dускорителям, звуковым картам, устройствам ввода информации. До появления DirectX разработчики, создававшие мультимедийные приложения для платформы Windows, должны были настраивать свои программы на работу с различными типами устройств и конфигураций. Теперь эта проблема устранена. DirectX Foundation содержит компонент, известный как "слой аппаратной абстракции" (Hardware Abstraction Layer, HAL), который использует программные
драйверы для обеспечения взаимодействия программных и аппаратных средств. В результате разработчики могут создавать единую версию приложения с использованием интерфейсов DirectX, не заботясь о том, чтобы оно работало на конкретных аппаратных конфигурациях. DirectX автоматически определяет технические возможности компьютера и устанавливает соответствующие параметры. DirectX также позволяет выполнять мультимедийные приложения, требующие аппаратной поддержки, отсутствующей на данном компьютере. В этом случае они программно эмулируются компонентом, который называется "слой аппаратной эмуляции" (Hardware Emulation Layer, HEL) и обеспечивает программные драйверы, работающие как недостающие устройства.
DirectX Media располагается над DirectX Foundation и обеспечивает высокоуровневые сервисы – поддержку анимации, потоковый вывод (возможность передачи и просмотра аудио- и видеоинформации по мере ее загрузки из Internet) и интерактивность. Автоматическая интеграция низкоуровневых сервисов, реализуемых DirectX Foundation, и высокоуровневых, реализованных в DirectX Media, облегчает процесс создания и воспроизведения мультимедийных элементов, позволяя разработчикам включать их в свои приложения и Web-страницы и обеспечивая тем самым недоступное ранее интерактивное мультимедийное содержимое. Кроме того, DirectX Media помогает решить задачу координации различных типов мультимедийных эффектов, облегчая синхронизацию их воспроизведения. Помимо двух указанных основных составляющих Microsoft DirectX в их состав также входят высокоуровневые компоненты, которые обеспечивают мультимедийные функции для Webприложений. К ним относятся: NetMeeting - средство для организации групповых онлайновых дискуссий и Windows Media Player - средство для передачи мультимедийного содержимого по Internet. Рассмотрим кратко основные ком-
поненты DirectX Foundation. К ним относятся Microsoft DirectDraw, Direct3D (режимы Immediate и Retained ) , DirectInput , DirectMusic , DirectSound ,
DirectSound 3D и DirectPlay . Эти программные интерфейсы системного уровня
обеспечивают эффективный доступ к различным компьютерным устройствам и обеспечивают реальную аппаратную независимость приложений, снимая проблемы установки драйверов и несовместимости аппаратно-программных платформ.
Microsoft Direct3D представляет собой интерфейс для работы с 3Dвидеокартами. Архитектура Direct3D представлена на рисунке 1.5.
Рисунок 1.5 – Архитектура Direct3D
Direct3D поддерживает два режима работы – Immediate Mode и Retained Mode . В режиме Immediate Mode Direct3D обеспечивает разработчикам аппаратную поддержку игровых и мультимедийных приложений в среде Microsoft Windows. Он позволяет добиться аппаратной независимости, поддерживает переключаемую Z-буферизацию и Intel ММХ-архитектуру процессоров. В этом режиме основные графические примитивы реализуются напрямую, без использования буферов выполнения (execute buffers).
Режим Retained Mode облегчает создание и анимацию трехмерных миров, поддерживая две новые функции: интерполяторы анимации со смешением цветов, плавными перемещениями объектов и множеством различных видов трансформации, а также последовательное заполнение сеточной структуры 3D-
объектов (meshes), позволяющее осуществлять их постепенную загрузку с удаленных серверов. Это дает возможность разработчикам эффективно использовать трехмерную графику, освобождая их от необходимости прямого управления структурами объектов на низком уровне.
Следует отметить, что Direct3D-приложения общаются с графическими устройствами одинаково, вне зависимости от режима. Они могут использовать или не использовать программную эмуляцию перед обращением к HAL. Реально Direct3D тесно интегрирован с компонентом DirectDraw, поэтому на рисунке 1.2 слой аппаратной абстракции HAL обозначен как DirectDraw/Direct3D HAL. Direct3D осуществляет Z-буферизацию и рендеринг поверхностей, а их непосредственное отображение выполняет DirectDraw. СОМ-интерфейс Direct3D является интерфейсом к DirectDraw.
DirectDraw - это менеджер управления памятью, обеспечивающий базовый набор функций для графических и мультимедийных приложений, работающих на платформе Windows. В отличие от традиционной Windows-графики DirectDraw использует прямой доступ к дисплейной памяти и графическим устройствам, обеспечивая при этом полную совместимость с Windowsприложениями.
На рисунке 1.6 показано взаимодействие между DirectDraw, компонентом ядра операционной системы GDI (Graphics Device Interface), слоем аппаратной абстракции (Hardware Abstraction Layer, HAL), и слоем аппаратной эмуляции
(Hardware Emulation Layer, HEL). Как видно, DirectDraw существует независи-
мо от GDI и оба интерфейса обладают возможностью прямого доступа к графическим устройствам через аппаратно-независимые слои. В отличие от GDI DirectDraw no возможности использует аппаратные функции. Если конкретное устройство не поддерживает требуемых функций, DirectDraw пытается их эмулировать, используя HEL. DirectDraw поддерживает работу с большим числом дисплейных адаптеров - от простых мониторов до сложных профессиональных устройств. Работая на уровне графических поверхностей, DirectDraw служит
базой для высокоуровневых графических функций и интерфейсов и позволяет использовать либо аппаратные возможности, предоставляемые устройствами, либо эмулировать их при необходимости.
3. Свободен (free) - блок адресов не выделен и не зарезервирован.
Резервирование и выделение памяти производится блоками. Начальный адрес бло-
ка должен быть выровнен на границу 64K (округляется вниз), а размер кратен размеру
страницы (округляется вверх). При выделении память обнуляется.
Для резервирования региона памяти в адресном пространстве процесса или выде-
ления ее используется функция VirtualAlloc, а для освобождения - функция VirtualFree.
Функция VirtualAlloc является базовой при выполнении операций управления вир-
туальным адресным пространством. Параметры этой функции определяют, какой объем
памяти необходимо выделить, в каком месте адресного пространства должен распола-
гаться выделенный фрагмент, закреплять ли за ним физическую память и какой вид за-
щиты следует установить. Функция возвращает адрес выделенного региона или NULL в
LPVOID VirtualAlloc ( LPVOID lpvAddress,
// адрес для размещения нового блока
// размер нового блока
DWORD fdwAllocationType,// зарезервировать адреса или закрепить
// нет доступа, только чтение
Функция VirtualAlloc сначала пробует найти область свободных адресов размером
dwSize байтов, которая начинается с адреса lpvAddress. Для этого она просматривает де-
рево VAD. Если необходимая область памяти свободна, функция возвращает значение
lpvAddress. В противном случае она просматривает все адресное пространство и ищет
свободный блок памяти достаточного размера. При обнаружении такого блока функция
возвращает его начальный адрес, иначе - значение NULL.
Аргумент fdwAllocationType может принимать значение MEM_RESERVE или
MEM_COMMIT либо оба значения одновременно. Для резервирования определенного
интервала адресов функция VirtualAlloc создает новый VAD, который отмечает исполь-
зуемую область. Однако эта функция не выделяет физическую память, из-за чего невоз-
можно использовать зарезервированные адреса. При попытке чтения или записи в заре-
зервированные страницы возникает ошибка доступа к памяти. С другой стороны,
никакая другая команда выделения памяти не может использовать ранее зарезервиро-
ванные адреса. Например, функции GlobalAlloc и malloc не могут разместить новые объ-
екты в области, которая пересекается с зарезервированным адресным пространством.
Попытка заставить функцию VirtualAlloc зарезервировать все доступное адресное про-
странство (1 Гб) приведет к конфликту: последующие операции выделения памяти не
будут выполняться, даже если указанная функция не задействовала никакой физической
Память не может быть закреплена, если она не зарезервирована. Комбинация фла-
гов MEM_RESERVE и MEM_COMMIT позволяет одновременно зарезервировать и за-
крепить указанную область памяти. Часто программисты вызывают функцию VirtualAl-
loc сначала с флагом MEM_RESERVE для резервирования большой области памяти, а
затем несколько раз подряд с флагом MEM_COMMIT для поэтапного закрепления от-
Флаг fdwProtect определяет, каким образом использовать определенную страницу
или диапазон страниц. Для резервируемой памяти этот флаг должен иметь значение
PAGE_NOACCESS. При закреплении памяти устанавливается флаг PAGE_READONLY
или PAGE_READWRITE. Другие программы не могут читать информацию из адресного
пространства вашего процесса, поэтому режим доступа только для чтения обеспечивает
защиту от ошибок в вашей программе, которые могут привести к случайному поврежде-
нию важной информации. Уровни защиты применимы к отдельным страницам. Различ-
ные страницы в одной области памяти могут иметь разные значения флага защиты. На-
пример, вы можете применить флаг PAGE_READONLY ко всему блоку, а затем
временно изменять уровень защиты отдельных страниц, разрешая доступ к ним для за-
писи. Защитить от записи только часть страницы невозможно, поскольку флаги устанав-
ливаются для целых страниц. В таблице 4.1. приведены возможные значения, которые
может принимать флаг fdwProtect.
Допускается только чтение
Допускается чтение и запись
Допускается только исполнение
Допускается исполнение и чтение
PAGE_EXECUTE_READWRITE Допускается исполнение чтение и запись
Дополнительный флаг защиты, который комбини-
руется с другими флагами. При первом обращении
к странице этот флаг сбрасывается и возникает ис-
ключение STATUS_GUARD_PAGE. Этот флаг ис-
пользуется для контроля размеров стека с возмож-
ностью его динамического расширения.
Запрещает кэширование страниц. Может быть поле-
зен при разработке драйверов устройств (например,
данные в видеобуфер должны переписываться сра-
зу, без кэширования)
Функция VirtualAlloc не может зарезервировать более 1 Гб памяти, поскольку про-
цесс контролирует только нижнюю половину своего адресного пространства объемом 2
Гб. В действительности объем контролируемой памяти еще меньше из-за свободных об-
ластей (по 64 Кб каждая) на границах адресного пространства процесса (рис. 8.2). Кроме
того, функция VirtualAlloc резервирует память фрагментами по 64 Кб, а закрепляет ее
фрагментами объемом в одну страницу. При резервировании памяти функция VirtualAl-
loc округляет аргумент lpvAddress до ближайшего значения, кратного 64 Кб. При закре-
плении памяти функция VirtualAlloc осуществляет одно из двух действий. Если аргу-
мент lpvAddress имеет значение NULL, функция VirtualAlloc округляет значение
аргумента dwsize до ближайшей границы между страницами. Если значение аргумента
lpvAddress не равно NULL, она закрепляет все страницы, содержащие хотя бы один байт
информации в диапазоне адресов от lpvAddress до lpvAddress + dwSize. Например, если
при выделении двух байтов памяти заданный адрес пересекает границу двух страниц,
закрепляются две целые страницы. В большинстве систем Windows 98 размер страницы
составляет 4 Кб, но если вы хотите проверить это значение, вызовите функцию GetSys-
По завершении процесса система автоматически освобождает использовавшуюся
им память. Освободить память, не дожидаясь окончания процесса, позволяет функция
BOOL VirtualFree (LPVOID lpvAddress,
// адрес освобождаемого блока
// размер освобождаемого блока
// перевести в резерв или освободить
Функция VirtualFree отменяет закрепление набора страниц, оставляя их адреса за-
резервированными, или полностью освобождает память, занимаемую этими страницами.
Закрепление можно отменять маленькими блоками, содержащими как зарезервирован-
ные, так и закрепленные страницы.
При освобождении зарезервированных адресов необходимо очищать весь выде-
ленный блок, причем все страницы этого блока должны находиться в одинаковом со-
стоянии - либо в закрепленном, либо в зарезервированном. Аргумент lpvAddress должен
содержать базовый адрес, возвращенный функцией VirtualAlloc. Значение аргумента
dwSize игнорируется, поскольку сразу освобождается весь выделенный диапазон: Аргу-
мент dwSize учитывается лишь при отмене закрепления отдельных фрагментов. Аргу-
мент fdwFreeType может принимать следующие значения:
MEM_RELEASE - освободить зарезервированный регион. При использовании этого
флага параметр dwSize должен быть равен нулю.
MEM_DECOMMIT - Освободить выделенную память.
В программах, где используются команды для работы с виртуальной памятью,
должен быть предусмотрен механизм "сбора мусора", обеспечивающий освобождение
страниц, которые становятся пустыми. В качестве такого механизма может применяться
низкоприоритетный поток, который время от времени просматривает выделенную об-
ласть и ищет пустые страницы.
Для изменения атрибутов защиты регионов используются функции VirtualProtect и
VirtualProtectEx. Причем, первая позволяет изменять атрибуты защиты в адресном про-
странстве текущего процесса, а вторая -произвольного. Рассмотрим подробнее функцию
Для управления памятью, прикладным программам предоставляются различные интерфейсы: (первые 3 применимы в наст.время):
· VirtualMemoryAPI – набор ф-ий, позволяющих приложению работать с вирт. адресным пространством: назначать физические страницы блоку адресов и освобождать их, устанавливать атрибуты защиты.
· MemoryMappedFileAPI – наборф-ий, позволяющих работать с файлами, отображаемыми в память; новый механизм, предоставляемый Win32API для работы с файлами и взаимодействия процессов;
· HeapMemoryAPI – набор ф-ий, позволяющих работать с динамически распределяемыми областями памяти (кучами).
· Local, GlobalMemoryAPI – набор ф-ий для работы с памятью, совместимых с х16 Windows (уже не используются).
· CRTMemoryAPI – ф-ии стандартной библиотеки языка С периода исполнения (runtime).
Интерфейс Virtual Memory.
VirtualMemoryAPI – набор ф-ий, позволяющих приложению работать с вирт. адресным пространством: назначать физические страницы блоку адресов и освобождать их, устанавливать атрибуты защиты.
Блок адресов адресного пространства процесса может нах-ся в одном из состояний:
-выделен (commited) – блоку адресов назначена физическая память, либо часть файла подкачки
-зарезервирован (reserved) – блок адресов помечен как занятый, но физическая память не распределена
-свободен (free) – блок адресов не выделен и не зарезервирован
При выделении память обнуляется.
Память сначала резервируется, потом выделяется.
VirtualAlloc () – выделяет память. Его параметры определяют: размер выделяемой памяти (не более 1 Гб), где в адресном пр-ве расположить выделенный фрагмент, надо ли закреплять физическую память, вид устанавливаемой защиты. Резервирует память фрагментами 64 кб, а закрепляет ее фрагментами объемом 1 страницу (4 кб).
VirtualProtect() –позволяет изменять атрибуты защиты в адресном пространстве текущего процесса.
VirtualProtectEx() –позволяет изменять атрибуты защиты в адресном пространстве произвольного процесса.
VirualQuery() – заполняет поля структуры информацией о заданном блоке памяти.
GlobalMemoryStatus() – определяет размер и свободный объем физической памяти, страничного файла и текущего адресного пространства.
GetSystemInfo() – возвращает размер системной физической страницы.
По завершении процесса ОС отменяет блокировку, освобождает использованную им память.
VirtualFree() – отменяет закрепление набора страниц, оставляя их адреса зарезервированными или освобождает память занимаемую этими страницами(даже заблокированные страницы).
Интерфейс Memory mapped file.
MemoryMappedFileAPI – набор ф-ий позволяющих работать с файлами, отображаемыми в память; новый механизм, предоставляемый Win32APIдля работы с файлами и взаимодействия процессов.
1. Исп-ся для запуска .exeи .dll.
-создания адресного простр-ва (размером 4 Гб)
-из ехефайластраницызагружаются в регион
-отображение в регион необходимыхdll.
2. Для работы с файлами.
-создается объект ядра «файл». CreateFile()
-создается объект ядра «проецируемый файл» CreateFileMapping(). Возвращает Handle.
-проецирование файла в вирт.память MapViewOfFile().
-убрать проецирование в память: UnmapViewFile().
Уничтожение объектов «файл», «проецируемый файл» - CloseHandle().
3. Для одновременного использования одной области данных несколькими процессами.
2 процесса могут использовать совместно, объект «проецируемый файл». При помощи MapViewOfFile() каждый процесс проецирует этот объект на свое адресное пространство и использует эту часть адресного пространства как разделяемую область данных.
Интерфейс Heap Memory.
HeapMemoryAPI – набор ф-ий, позволяющих работать с динамически распределяемыми областями памяти (кучами).
Куча – блок памяти, из которого прога при необходимости выделяет себе более мелкие фрагменты.
Причины группировки выделенных блоков:
-позволяет отделить и защитить группу связанных блоков.
-если все узлы связного списка находятся в одной куче, а узлы двоичного дерева – в другой, то ошибка одного алгоритма в меньшей степени скажется на работе другого алгоритма.
-объекты памяти, работающие совместно могут быть сгруппированы => подкачка страниц сводится к минимуму.
GetProcessHeap() – получить дескриптор стандартной кучи (по умолчанию) памяти.
HeapCreate() – создает кучу. В параметрах указывается начальный размер кучи и максимальный размер кучи (если он =0, то размер кучи ограничивается объемом доступной памяти).
HeapAlloc() – выделение блоков памяти из кучи.
HeapReAlloc() – повторное выделение…(изменение размера блока, после его выделения).
HeapFree() – освобождение блоков памяти.
HeapSize() –узнать точный размер любого блока.
HeapDestroy() – уничтожение «кучи».
Организация стока поверхностных вод: Наибольшее количество влаги на земном шаре испаряется с поверхности морей и океанов (88‰).
Общие условия выбора системы дренажа: Система дренажа выбирается в зависимости от характера защищаемого.
Поперечные профили набережных и береговой полосы: На городских территориях берегоукрепление проектируют с учетом технических и экономических требований, но особое значение придают эстетическим.
© cyberpedia.su 2017-2020 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!
Virtual Memory api - набор функций, позволяющих приложению работать с виртуальным адресным пространством: назначать физические страницы блоку адресов и освобождать их, устанавливать атрибуты защиты.
Memory Mapped File API - набор функций, позволяющий работать с файлами, отображаемыми в память. Новый механизм, предоставляемый Win32 API для работы с файлами и взаимодействия процессов.
Heap Memory API - набор функций, позволяющих работать с динамически распределяемыми областями памяти (кучами).
Local, Global Memory API - набор функций работы с памятью, совместимых с 16-битной Windows. Следует избегать их использования.
CRT Memory API - функции стандартной библиотеки языка “С” периода исполнения (runtime).
Два последних набора функций в настоящем курсе не рассматриваются.
Менеджер виртуальной памяти
VMM (Virtual Memory Manager)
управление виртуальным адресным пространством процесса;
разделение памяти между процессами;
защита виртуальной памяти одного процесса от других процессов.
Менеджер ВП обеспечивает для процессов следующие наборы функций:
управление виртуальным адресным пространством процесса;
разделение памяти между процессами;
защита виртуальной памяти одного процесса от других процессов.
Адресное пространство процесса
В Windows NT используется плоская (flat) модель памяти. Каждому процессу выделяется "личное" изолированное адресное пространство. На 32-разрядных компьютерах размер этого пространства составляет 4 Гбайт и может быть расширен до 32 Гбайт при работе Windows NT 5.0 на процессоре Alpha.
В Windows NT 4.0 младшие 2 Гбайт памяти выделяются процессу для произвольного использования, а старшие 2 Гбайт резервируются и используются операционной системой. В младшую часть адресного пространства помещаются и некоторые системные динамически связываемые библиотеки (DLL). Желание расширить доступное процессу адресное пространство привело к тому, что Windows NT 4.0 Enterprise процессу выделяется дополнительный 1 Гбайт за счет сокращения системной области.
Средства защиты памяти
Отдельное адресное пространство для каждого процесса. Аппаратура запрещает процессу доступ к физическим адресам другого процесса.
Два режима работы: режим ядра, в котором процессам разрешен доступ к системным данным, и пользовательский режим, в котором это запрещен.
Страничный механизм защиты. Каждая виртуальная страница имеет набор признаков, который определяет разрешенные типы доступа в пользовательском режиме и в режиме ядра.
Объектно-ориентированная защита памяти. Каждый раз, когда процесс открывает указатель на секцию, монитор ссылок безопасности проверяет, разрешен ли доступ процесса к данному объекту.
Каждый раз, когда нить использует адрес, менеджер ВП вместе с аппаратными средствами транслирует виртуальный адрес в физический. Подсистема виртуальной памяти, управляя процессом трансляции виртуальных адресов, гарантирует, что нить одного процесса не сможет получить доступ к физической странице памяти, относящейся к другому процессу.
В дополнение к прямой защите, обеспечиваемой механизмом трансляции, каждый процессор, который поддерживает виртуальную память, реализует некоторую форму аппаратно-управляемой защиты памяти. Часто аппаратная защита бывает минимальной. Из-за этого менеджер виртуальной памяти Windows NT в гораздо большей степени зависит от аппаратуры, чем другие части операционной системы.
Каждый процесс NT executive имеет большое виртуальное адресное пространство размером в 4Гб, из которых 2 Гб резервируются для системных нужд. (Процессор MIPS R4000 требует, чтобы 2 Гб адресного пространства были зарезервированы для системы. Хотя другие процессоры требуют меньше, для переносимости системы Windows NT всегда резервирует 2 Гб.)
терфейсов существует достаточно много, но все их можно разделить на два класса: универсальные и специализированные.
Универсальные API являются общими для всех 3D-акселераторов, а поддержка аппаратного ускорения для этих API возлагается на сами ускорители. В первую очередь здесь следует выделить Microsoft DirectX и OpenGL . Оба они используются, в основном, в программах компьютерной анимации.
Специализированные API предназначены для работы с графическими акселераторами, построенными на определенных 3D-чипсетах; наиболее известными среди них являются Glide API – интерфейс для работы с чипами VooDoo ® ; Metal – для чипов Savage3D и т.п. Программы, написанные с использованием специализированных API, работают только на тех акселераторах, под которые создавались эти API. Большинство специализированных API предоставляет только низкоуровневый интерфейс программирования, однако в последнее время, новые версии DirectX включают интерфейсы высокоуровневой поддержки, такие как DirectX for VisualBasic , который осуществляет языковую поддержку мультимедиа-приложений, написанных в среде визуального программирования Visual Basic.
Читайте также: