Кучи и менеджеры куч
Серьезные приложения интенсивно используют механизмы выделения и освобождения памяти. В коммерческих приложениях широко применяются такие элементы, как: динамические массивы, строки, объекты и многое другое. При этом, создание и удаление подобных элементов происходит довольно часто, а сами элементы имеют относительно небольшой размер.
Такая работа по выделению памяти и ее освобождению, по отношению к элементам небольшого размера, является неэффективной. Во-первых, снижается производительность, т. к. резервирование адресного пространства и выделение страниц памяти происходит на уровне ядра операционной системы. Во-вторых, теряются большие объемы памяти. Например, если приложение требует выделить 256 байт под строку, операционная система реально выделяет одну страницу памяти, объемом 4 или 8 килобайт (в зависимости от операционной системы).
Для решения проблемы выделения памяти небольшим элементам приложения была введена организация по принципу кучи (heap). Куча - это достаточно большой непрерывный участок памяти, из которого выделяются небольшие блоки. Для того чтобы куча могла функционировать, в операционную систему был включен так называемый менеджер кучи. Менеджер кучи - это специальный механизм, который следит за выделением и освобождением блоков памяти. Для каждого вновь созданного процесса Windows по умолчанию создает кучу. Все кучи, которые создаются операционной системой, являются потокобезопасными. Следовательно, у программиста есть возможность обращаться к одной куче из разных потоков одновременно. Для работы с менеджером кучи Win32 API можно пользоваться следующими функциями (табл. 1.10).
Таблица 1.10. Функции Win32 API для работы с кучей
|
|
|
|
|
Функция
|
Назначение
|
|
|
HeapCreate
|
Резервирует непрерывный блок памяти в виртуальном адресном пространстве процесса, т. е. создает кучу
|
|
|
HeapAlloc
|
Выделяет блок неперемещаемой памяти в куче
|
|
|
HeapReAlloc
|
Служит для изменения размера блока памяти, выделенного функцией HeapAlloc
|
|
|
HeapFree
|
Освобождает блок памяти, выделенной функцией HeapAlloc
|
|
|
HeapDestroy
|
Уничтожает кучу, созданную с помощью функции
HeapCreate
|
|
|
VirtualAlloc
|
Резервирует или размещает страницы в виртуальной памяти процесса
|
|
|
VirtualFree
|
Освобождает страницы в виртуальной памяти процесса
|
|
|
VirtualLock
|
Защищает диапазон адресов от переноса в страницу памяти
|
|
|
VirtualUnlock
|
Снимает защиту, установленную функцией VirtualLock
|
|
|
VirtualQuery
|
Выдает информацию о диапазоне страниц в виртуальной памяти процесса, вызвавшего данную функцию
|
|
|
VirtualQusryEx
|
То же, что И VirtualQuery, только для определенного процесса
|
|
|
VirtualProtect
|
Изменяет права доступа к определенному диапазону памяти в адресном пространстве процесса, вызвавшего данную функцию
|
|
|
VirtualProtectEx
|
То же, что и VirtualProtect, только для определенного процесса
|
|
|
|
|
|
Кроме перечисленных в табл. 1.10, существуют еще функции LocalAlloc (GlobalAlloc) и LocalFree (GlobalFree). Вы можете использовать любое на-писание функций, т. к. в Win32 нет разделения на глобальные и локальные кучи. Данные функции применяются, в основном, при работе с буфером обмена Windows. Эти функции являются устаревшими и не рекомендуются к использованию.
Кроме стандартного менеджера кучи, который предлагает Microsoft, создателями Delphi был предложен свой менеджер кучи, который поставляется вместе с Delphi. Менеджер кучи Delphi резервирует блоки виртуальной памяти размером 1 Мбайт. Размер выделяемых Delphi блоков реальной памяти - 16 Кбайт. При работе с менеджером куч Delphi можно использовать следующие функции:
- New, Dispose - применяются для выделения и освобождения памяти. Используются для динамической работы с элементами приложения;
- GetMem, FreeMem - также применяются для выделения и освобождения памяти. Используются для динамической работы с небольшими двоичными блоками памяти (блоки, буферы и т. п.).
Кроме вышеперечисленных менеджеров куч, программисту предоставлена возможность создания собственного менеджера. .
Содержание раздела