8.4.1. Стратегия выделения динамической памяти

На верх  Назад  Вперёд

Куча – это память, структура которой организована в виде стека. «Дно» кучи хранится в переменной HeapOrg. Изначально указатель кучи (HeapPtr) ссылается на дно кучи. Если переменной выделяется динамическая память в куче, то HeapPtr увеличивается на размер выделенного блока памяти. Это имеет эффект «складывания» динамических переменных друг на друга.

Каждый раз, когда выделяется блок памяти, его размер нормализуется, чтобы он был кратен 16 (или 32 на 64-разрядных системах) байтам.

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

Список свободной кэш-памяти в действительности является КЭШем свободных блоков кучи, которые имеют определённую длину (скорректированный размер блока, делённый на 16, даёт индекс в таблице списка свободной кэш-памяти). Это является более быстрым доступом, чем поиск через весь список freelist.

Формат записи в freelist является следующим:

PFreeRecord = ^TFreeRecord;
TFreeRecord = record
  Size : longint;
  Next : PFreeRecord;
  Prev : PFreeRecord;
end;

Поле Next указывает на следующий свободный блок, в то время как поле Prev указывает на предыдущий свободный блок.

Алгоритм выделения памяти следующий:

1.Размер блока для выделения кратен 16 (или 32)

2.Список свободного КЭШа просматривается для поиска свободного блока указанного или большего размера, если такой блок найден, то память выделяется и выполняется выход из процедуры

3.freelist просматривается для поиска свободного блока указанного или большего размера, если такой блок найден, то память выделяется и выполняется выход из процедуры

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

5.Если куча не может быть увеличена, то библиотека времени выполнения генерирует ошибку 203