Визуальное программирование и MFC

       

Функция VirtualAlloc: переданная и зарезервированная память


Если программе нужна динамически распределяемая память, то рано или поздно ей придется вызвать функцию VirtualAlloc. Скорее всего вызовете ее не программист, а функции Windows или библиотеки С периода выполнения, выделяющие память из кучи. Зная, как работает VirtuаlAlloc, можно лучше понять функции, которые обращаются к ней.

Сначала разберемся с понятиями зарезервированной (reserved) и переданной (committed памяти. При резервировании памяти выделяется непрерывный диапазон виртуальных адресов. Если, допустим, известно, что программа будет оперировать с одним 5-мегабайтным блоком памяти (блоки памяти называют также регионами (regions)), но весь он сейчас не нужен, тогда следует вызвать VirtualAlloc и в параметре, определяющем тип выделения памяти, указать MEM_RESERVE, а в параметре, задающем размер выделяемой памяти, — 5 Мб. Windows округляет начальный и конечный адреса региона до значений, кратных 64 Кб, и уже не даст процессу повторно зарезервировать память из этого региона. И хотя программист может задавать начальный адрес региона, лучше оставить это занятие самой Windows. Ну вот, собственно, и все. Больше ничего не происходит — не выделяется ни оперативной памяти, ни пространства в файле подкачки.

Когда программе всерьез понадобится эта память, она снова вызовет VirtualAlloc, на этот раз ука, МЕМ_СОММIТ, чтобы передать память из этого региона. Теперь начальный и конечный адреса региона округляются до значений, кратных 4 Кб, и в файле подкачки выделяются соответствующие страницы, а также создается нужная таблица страниц. Блок помечается либо как "только для чтения", либо как "для чтения и записи". Однако оперативная память по-прежнему не выделяется; это произойдет, лишь когда программа попытается что-то записать в этот блок памяти. Если передаваемая память не была ранее зарезервирована, ошибки все равно не возникает. А если память уже была передана, то и в этом случае — никаких проблем. Главное в том, что перед использованием память должна быть передана.

Чтобы вернуть (decommit) переданную память (по сути, вернуть соответствующим страницам статус зарезервированных), применяется функция VirtualFree. Она может также освободить и зарезервированный регион памяти, но для этого ей надо передать базовый адрес, возвращенный VirtualAlloc в момент резервирования памяти.



Содержание раздела