Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
СПО от Тихомирова / Лаб работы СПО ЗО 2014 / Управление виртуальной памятью 5 лр.doc
Скачиваний:
12
Добавлен:
08.06.2015
Размер:
134.14 Кб
Скачать

1.4. Резервирование регионов виртуального адраесного пространства

Приложение резервирует регион в адресном пространстве, используя функцию

VirtualAlloc (lpvAddress: Pointer; dwSize, flAllocationType, flProtect: DWORD): Pointer;

Первый параметр определяет положение резервируемого региона в адресном пространстве. Если параметр равен Nil, система определяет положение региона самостоятельно. Регионы всегда резервируются на границе 64К.

Если запрос выполнен, функция возвращает базовый адрес зарезервированного региона.

Второй параметр задает размер резервируемого региона в байтах. Заданный размер увеличивается до величины, кратной размеру страницы.

Третий параметр определяет вид операции – MEM_RESERVE – зарезервировать регион, MEM_COMMIT - передать региону физическую память (сначала нужно зарезервировать регион, затем передать ему память).

При указании параметра MEM_TOP_DOWNсистема размещает регион по максимально возможному адресу -Allocatesmemoryatthehighestpossibleaddress. Это дает возможность уменьшитьфрагментациювиртуального адресного пространства.

В принципе можно одновременно зарезервировать регион и передать ему физическую память – например

VirtualAlloc (Nil, 100*1024, MEM_RESERVE OR MEM_COMMIT, PAGE_READWRITE);

Последний параметр определяет атрибут защиты.

Для возврата физической памяти, спроецированной на регион, или освобождения всего региона адресного пространства используется функция

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;

1.5. Использование куч

Процессу разрешено создавать несколько куч, являющихся частью его адресного пространства.

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

Одна куча предоставляется процессу по умолчанию. Ее описатель возвращает функция

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