Читайте также: |
|
Members
BaseAddress
A pointer to the base address of the region of pages.
AllocationBase
A pointer to the base address of a range of pages allocated by the VirtualAlloc function. The page pointed to by the BaseAddress member is contained within this allocation range.
AllocationProtect
The memory protection option when the region was initially allocated. This member can be one of the memory protection constants or 0 if the caller does not have access.
RegionSize
The size of the region beginning at the base address in which all pages have identical attributes, in bytes.
State
The state of the pages in the region. This member can be one of the following values.
State | Meaning |
MEM_COMMIT 0x1000 | Indicates committed pages for which physical storage has been allocated, either in memory or in the paging file on disk. |
MEM_FREE 0x10000 | Indicates free pages not accessible to the calling process and available to be allocated. For free pages, the information in the AllocationBase, AllocationProtect, Protect, and Type members is undefined. |
MEM_RESERVE 0x2000 | Indicates reserved pages where a range of the process's virtual address space is reserved without any physical storage being allocated. For reserved pages, the information in the Protect member is undefined. |
Protect
The access protection of the pages in the region. This member is one of the values listed for the AllocationProtect member. Type
The type of pages in the region. The following types are defined.
Type | Meaning |
MEM_IMAGE 0x1000000 | Indicates that the memory pages within the region are mapped into the view of an image section. |
MEM_MAPPED 0x40000 | Indicates that the memory pages within the region are mapped into the view of a section. |
MEM_PRIVATE 0x20000 | Indicates that the memory pages within the region are private (that is, not shared by other processes). |
Memory Protection Constants
The following are the memory-protection options; you must specify one of the following values when allocating or protecting a page in memory. Protection attributes cannot be assigned to a portion of a page; they can only be assigned to a whole page. Protection attributes specified when protecting a page cannot conflict with those specified when allocating a page.
Constant/value | Description |
PAGE_EXECUTE 0x10 | Enables execute access to the committed region of pages. An attempt to read or write to the committed region results in an access violation. This flag is not supported by the CreateFileMapping function. |
PAGE_EXECUTE_READ 0x20 | Enables execute and read access to the committed region of pages. An attempt to write to the committed region results in an access violation. Windows Server 2003 and Windows XP:This attribute is not supported by the CreateFileMapping function until Windows XP SP2 and Windows Server 2003 SP1. |
PAGE_EXECUTE_READWRITE 0x40 | Enables execute, read, and write access to the committed region of pages. Windows Server 2003 and Windows XP:This attribute is not supported by the CreateFileMapping function until Windows XP SP2 and Windows Server 2003 SP1. |
PAGE_EXECUTE_WRITECOPY 0x80 | Enables execute, read, and write access to the committed region of image file code pages. The pages are shared read-on-write and copy-on-write. This flag is not supported by the VirtualAlloc, VirtualAllocEx, or CreateFileMapping functions. |
PAGE_NOACCESS 0x01 | Disables all access to the committed region of pages. An attempt to read from, write to, or execute the committed region results in an access violation exception, called a general protection (GP) fault. This flag is not supported by the CreateFileMapping function. |
PAGE_READONLY 0x02 | Enables read access to the committed region of pages. An attempt to write to the committed region results in an access violation. If the system differentiates between read-only access and execute access, an attempt to execute code in the committed region results in an access violation. |
PAGE_READWRITE 0x04 | Enables both read and write access to the committed region of pages. |
PAGE_WRITECOPY 0x08 | Gives copy-on-write protection to the committed region of pages. This flag is not supported by the VirtualAlloc or VirtualAllocEx functions. |
The following are modifiers that can be used in addition to the options provided in the previous table, except as noted.
Constant/value | Description |
PAGE_GUARD 0x100 | Pages in the region become guard pages. Any attempt to access a guard page causes the system to raise a STATUS_GUARD_PAGE_VIOLATION exception and turn off the guard page status. Guard pages thus act as a one-time access alarm. When an access attempt leads the system to turn off guard page status, the underlying page protection takes over. If a guard page exception occurs during a system service, the service typically returns a failure status indicator. This value cannot be used with PAGE_NOACCESS. This flag is not supported by the CreateFileMapping function. |
PAGE_NOCACHE 0x200 | Does not allow caching of the committed regions of pages in the CPU cache. The hardware attributes for the physical memory should be specified as "no cache." This is not recommended for general usage. It is useful for device drivers, for example, mapping a video frame buffer with no caching. This value cannot be used with PAGE_NOACCESS. This flag is not supported by the CreateFileMapping function. |
PAGE_WRITECOMBINE 0x400 | Enables write-combined memory accesses. When enabled, the processor caches memory write requests to optimize performance. Thus, if two requests are made to write to the same memory address, only the more recent write may occur. Note that the PAGE_GUARD and PAGE_NOCACHE flags cannot be specified with PAGE_WRITECOMBINE. If an attempt is made to do so, the SYSTEM_INVALID_PAGE_PROTECTION NT error code is returned by the function. This flag is not supported by the CreateFileMapping function. |
Более широкими возможностями обладает функция VirtualQueryEx (
HANDLE hProcess, // handle of process – описатель процесса, о виртуальном адресном пространстве которого необходимо получить информацию
LPCVOID lpAddress, // address of region
PMEMORY_BASIC_INFORMATION lpBuffer, // address of information buffer
DWORD dwLength // size of buffer
);
Эта функция отличается от предыдущей тем, что дает возможность получить информацию о виртуальном адресном пространстве любого процесса, для которого известен его описатель.
4. Приложение резервирует регион в адресном пространстве, используя функцию
VirtualAlloc(lpvAddress: Pointer; dwSize, flAllocationType, flProtect: DWORD): Pointer;
Первый параметр определяет положение резервируемого региона в адресном пространстве. Если параметр равен Nil, система определяет положение региона самостоятельно. Регионы всегда резервируются на границе 64К.
Если запрос выполнен, функция возвращает базовый адрес зарезервированного региона.
Второй параметр задает размер резервируемого региона в байтах. Заданный размер увеличивается до величины, кратной размеру страницы.
Третий параметр определяет вид операции – MEM_RESERVE – зарезервировать регион, MEM_COMMIT - передать региону физическую память (сначала нужно зарезервировать регион, затем передать ему память).
При указании параметра MEM_TOP_DOWN система размещает регион по максимально возможному адресу - Allocates memory at the highest possible address. Это дает возможность уменьшить фрагментацию виртуального адресного пространства.
В принципе можно одновременно зарезервировать регион и передать ему физическую память – например
VirtualAlloc (Nil, 100*1024, MEM_RESERVE OR MEM_COMMIT,PAGE_READWRITE);
Последний параметр определяет атрибут защиты.
5. Для возврата физической памяти, спроецированной на регион, или освобождения всего региона адресного пространства используется функция
VirtualFree (lpAddress: Pointer; dwSize,: DWORD): BOOL;
В простейшем случае использования этой функции – для освобождения всей переданной региону физической памяти – в параметр lpAddress необходимо передать базовый адрес региона, в параметр dwSize=0, так как системе известен размер региона. В третьем параметре следует передать MEM_RELEASE – это приведет к возврату системе всей физической памяти, спроецированной на регион, и освобождению самого региона. Если необходимо не освобождая регион вернуть в систему часть физической памяти, переданной региону, в параметр lpAddress заносится адрес, идентифицирующий первую возвращаемую страницу, в параметр dwSize – количество возвращаемых байт, в параметре dwFreeType - MEM_DECOMMIT.
Пример 1 использования рассмотренных выше функций для просмотра виртуального адресного пространства и вывода списка имен модулей, размещенных в нем, и их базовых адресов.
var
mbi: TMemoryBasicInformation;
lp: cardinal;
buf: array [0..400] of char;
begin
lp:=0;
Listbox1.Clear;
while VirtualQuery (pointer(lp),mbi, sizeof(mbi))=sizeof (mbi) do
begin
if (mbi.State<>MEM_FREE) then
begin
if GetModuleFileName (integer(mbi.BaseAddress), buf, sizeof(buf))>0
then
Listbox1.Items.Add (buf + inttostr(cardinal(mbi.BaseAddress))
end;
lp:=lp+mbi.RegionSize;
end;
КУЧИ
Процессу разрешено создавать несколько куч, являющихся частью его адресного пространства.
Куча - это регион зарезервированного адресного пространства. Первоначально большей его части физическая память не передается. После того, как программа занимает эту область под данные, диспетчер, управляющий кучами, передает ей страницы физической памяти. При освобождении страниц в куче диспетчер возвращает физическую память системе.
Одна куча предоставляется процессу по умолчанию. Ее описатель возвращает функция
GetProcessHeap(): Handle;
Дополнительные кучи создаются вызовом функции
HeapCreate (flOption, dwInitialSize, MaximumSize): Handle;
Первый параметр определяет характер операций, выполняемых над кучей. По умолчанию (значение 0) действует принцип последовательного доступа к куче (как к критическому участку).
Второй параметр определяет количество байт, первоначально передаваемых куче.
Третий параметр указывает максимальный размер кучи. Может быть равен 0 - в этом случае система резервирует регион, самостоятельно определяя его размер и при необходимости расширяет его до максимально возможного объема.
Выделение блока памяти из кучи выполняет функция
HeapAlloc (Handle, dwFlags, dwBytes): pointer;
Первый параметр - описатель кучи, возвращаемый функциями GetProcessHeap() или HeapCreate()
Второй параметр указывает на характер выделения памяти. При его значении, равным HEAP_ZERO_MEMORY=8, выделяемый блок заполняется нулями.
Третий параметр определяет число выделяемых в куче байт.
Освобождение блока памяти выполняет функция
HeapFree (Handle, dwFlags, dwBytes): Boolean;
Уничтожение кучи выполняет функция HeapDestroy (Handle): Boolean.
Значения символических констант для операций с кучами:
HEAP_NO_SERIALIZE 0x00000001
HEAP_GROWABLE 0x00000002
HEAP_GENERATE_EXCEPTIONS 0x00000004
HEAP_ZERO_MEMORY 0x00000008
HEAP_REALLOC_IN_PLACE_ONLY 0x00000010
HEAP_TAIL_CHECKING_ENABLED 0x00000020
HEAP_FREE_CHECKING_ENABLED 0x00000040
HEAP_DISABLE_COALESCE_ON_FREE 0x00000080
HEAP_CREATE_ALIGN_16 0x00010000
HEAP_CREATE_ENABLE_TRACING 0x00020000
HEAP_MAXIMUM_TAG 0x0FFF
HEAP_PSEUDO_TAG_FLAG 0x8000
HEAP_TAG_SHIFT 18
Файлы, проецируемые в память
Как и виртуальная память, проецируемые файлы позволяют резервировать регион адресного пространства и передавать ему физическую память. При использовании проецируемых файлов физическая память не выделяется из системного страничного файла, а берется из файла, уже находящегося на диске. Как только файл спроецирован в память, к нему можно обращаться так, будто он целиком в нее загружен.
Описанный механизм управления памятью применяется для:
· загрузки и исполнения EXE- и DLL-файлов. Это позволяет существенно экономить как на размере страничного файла, так и на времени, необходимом системе для подготовки приложения к исполнению;
· доступа к файлу данных, размещенному на диске. Это позволяет обойтись без операций файлового ввода/вывода и буферизации содержимого файла - не нужно выделять память под буфер, загружать данные из файла в память;
· обеспечения совместного доступа разных процессов к общим данным.
Подготовка к использованию файлов, проецируемых в память
Для этого нужно выполнить три операции:
1. Создать или открыть объект ядра "файл".
2. Создать объект ядра "проецируемый файл", чтобы сообщить системе размер файла и способ доступа к нему.
3. Указать системе, как спроецировать в адресное пространство процесса созданный в п.2 объект - целиком или только его часть.
Для завершения работы с файлом, проецируемым в память, следует выполнить три операции:
1. Сообщить системе об отмене проецирования на адресное пространство процесса объекта ядра "проецируемый файл".
2. Закрыть этот объект.
3. Закрыть объект ядра "файл".
Пример 2. Чтение содержимого текстового файла
1 этап – создание или открытие файла
var Hfile: Thandle;
hMapping: Thandle;
HighSize: Dword;
Data: Pointer;
Hfile:= CreateFile (Pchar (FileName),
Generic_Read, // способ доступа
File_Share_Read,
nil, // атрибут защиты
OPEN_EXISTING,
FILE_FLAG_SEQUENTIAL_SCAN, // способ чтения
0);
if (Hfile =0) then exit; // делать больше нечего
2 этап – создание объекта проецируемый файл
hMapping:= CreateFileMapping (hFile,
nil,
PAGE_READONLY,
0,0, // старшие и младшие разряды максимального размера
// файла - для существующего файла размер известен и не указывается
nil);
CloseHandle (Hfile);
if hMapping=0 then exit;
3 этап – проецирование данных на адресное пространство процесса
Data:= MapViewOfFile (hMapping,
FILE_MAP_READ, // доступ WRITE, ALL _ ACCESS
0, // смещение
0, // от начала файла оконного представления
0); // размер окна 0 – весь файл
// Переслать данные в компонент Memo1
memo1.SetTextBuf(data);
ДАННЫЕ ФАЙЛА ПОЯВИЛИСЬ НА ЭКРАНЕ, хотя считывания файла в явном виде не было!
Завершение работы с файлом
1 этап - отсоединение данных от адресного пространства процесса
Выполняется функцией UnmapViewOfFile (Data)
Для записи изменений, выполненных в памяти, в дисковое представление файла используется функция FlushViewOfFile (data, количество_байтов)
2 и 3 этапы. Выполняется закрытие объектов "проецируемый файл" и "файл" с помощью функции CloseHandle().
Пример 3. Проецирование непосредственно на физическую память из страничного файла для создания приложения, допускающего запуск единственной копии.
Для передачи данных между процессами можно использовать проецирование непосредственно на физическую память из системного страничного файла (соответствующий пример приведен в работе " Средства обмена данными между приложениями "). Этап 1 (создание файла) не выполняется, в параметре Hfile функции CreateFileMapping передается $FFFFFFFF. Создаваемый этой функцией именованный объект должен быть уникальным в системе. Это обстоятельство дает возможность создавать приложения с возможностью запуска единственной копии.
program Project1;
uses
Forms, windows,
Unit1 in 'Unit1.pas' {Form1};
{$R *.RES}
var un:Thandle;
begin
un:=CreateFileMapping($FFFFFFFF,nil,Page_ReadOnly,0,32,'Myapp');
if GetLasterror = ERROR_Already_Exists
then
begin
// ShowMessage('2');
halt;
end;
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
В приведенном примере блок совместно используемой памяти выделяется в системном страничном файле (на это указывает первый параметр функции CreateFileMapping). Если при создании блока будет получен код ошибки ERROR_Already_Exists, это свидетельствует о наличии работающей копии приложения. В этом случае приложение завершается, в противном случае процесс инициализации продолжается.
ВЫПОЛНЕНИЕ РАБОТЫ
1. Написать приложение, реализующие следующие функции:
- вывод на экран системной информации;
- мониторинг (запуск по кнопке) состояния разделов виртуальной памяти (показатели - общий объем свободной, зарезервированной и выделенной -commit- памяти, количество зарезервированных и распределенных участков памяти, их размеры и базовые адреса;
- резервирование региона задаваемого размера с размещением с задаваемого адреса (по кнопке);
- резервирование региона задаваемого размера без указания адреса (по кнопке) с параметром MEM_TOP_DOWN и без него;
- проецирование физической памяти задаваемого размера на регион (по кнопке);
- возврат системе физической памяти из выбранного региона (по кнопке);
- освобождение региона (по кнопке);
- размещение в куче процесса по умолчанию списка из N cлов (по кнопке);
- cоздание кучи и размещение в ней списка из M элементов по R байт в каждом (по кнопке). Значения N, M и R должны задаваться в окнах редактирования.
2. Проверить работу приложения. Обратить внимание на изменение состояния виртуального адресного пространства процесса после резервирования, освобождения региона, размещения списков. Сравнить размер свободной виртуальной памяти, возвращаемый в поле dwAvailVirtual функцией GlobalMemoryStatus, и общий размер всех свободных блоков виртуальной памяти, определяемый разработанным приложением.
3. Выполнить чтение текстового файла, используя метод проецирования файла на виртуальное адресное пространство. Добавить возможность сохранения содержимого файла после редактирования (по желанию).
ОТЧЕТ О РАБОТЕ
1. Демонстрация экранных форм разработанного приложения.
2. В ПИСЬМЕННОМ виде - системная информация – название параметра и его значение.
3. Влияние параметра MEM_TOP_DOWN на значение базового адреса резервируемого региона.
4. Программа чтения содержимого текстового файла с использованием метода его проецирования на виртуальное адресное пространство и (по желанию) его сохранения после выполнения редактирования.
Контрольные вопросы
1. Какие модули размещаются в адресном пространстве процесса?
2. Каков диапазон адресов виртуального адресного пространства, возвращаемый функцией VirtualQuery()?
3. Как можно уменьшить фрагментацию виртуального адресного пространства?
4. Как отразилось на состоянии разделов виртуальной памяти размещение списков в кучах - в каких регионах (0-1 Гб, 1-2 Гб) выделялась память и какого размера.
5. Перечислите возможные значения состояния страниц виртуальной памяти.
6. Какие атрибуты защиты страниц виртуальной памяти использует MS Windows XP?
7. Как выполняется проецирование файла на виртуальное адресное пространство.
Дата добавления: 2015-07-11; просмотров: 111 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Структура программы. | | | СОЗДАНИЕ МНОГОСТРАНИЧНОГО ДОКУМЕНТА |