Подсистема управления динамически распределяемой областью памяти
Динамически распределяемая область — это похожая на стек структура, которая увеличивается, начиная от младших адресов памяти. При этом используется сегмент динамически распределяемой области. Нижняя граница динамически распределенной области запоминается в переменной HeapOrg, а верхняя граница динамически распределяемой области соответствует нижней границе свободной памяти и сохраняется в переменной HeapPtr. При каждом выделении динамической переменной подсистема динамического распределения памяти перемещает переменную HeapPtr вверх на размер переменной, как бы организуя при этом стек динамических переменных, в котором одна переменная размещается за другой.
Переменная HeapPtr после каждой операции нормализуется, и смещение принимает значение от $0000 до $000f . Так как каждая переменная должна целиком содержаться в одном сегменте, максимальный размер отдельной переменной, которая должна быть размещена в динамически распределяемой области, составляет 65521 байт, что соответствует $10000 минус $000f.
Методы освобождения областей динамически распределяемой памяти
Динамические переменные, сохраняемые в динамически распределенной области, освобождаются одним из двух способов:
1. с помощью процедур Dispose и FreeMem;
2. С помощью процедур Mark и Release.
Простейшей схемой использования процедур Mark и Release является выполнение следующих операторов:
New(Ptr1);
New(Ptr2);
Mark(P);
New(Ptr3);
New(Ptr4);
New(Ptr5);
Схема динамически распределяемой области при этом будет выглядеть следующим образом:
Ptr1
Ptr2
Ptr3
Ptr4
Ptr5
HeapPtr
Младшие адреса памяти
Старшие адреса памяти
Содержимое Ptr1
Содержимое Ptr2
Содержимое Ptr3
Содержимое Ptr4
Содержимое Ptr5
Оператор Mark(P) отмечает состояние динамически распределенной области непосредственно перед выделение памяти для переменной Ptr3 (путем сохранения текущего значения переменной HeapPtr в P). Если выполняется оператор Release(P), то схема динамически распределенной области становится следующей:
Ptr1
Ptr2
HeapPtr
Младшие адреса памяти
Старшие адреса памяти
Содержимое Ptr1
Содержимое Ptr2
При этом освобождается вся память, выделенная под все указатели.
Выполнение процедуры Release(HeapOrg) полностью освобождает динамически распределенную область памяти, поскольку переменная HeapOrg указывает на нижнюю границу динамически распределяемой области.
Применение Процедур Mark и Release для освобождения памяти в порядке обратному тому, в котором происходило выделение памяти, весьма эффективно. Однако для большинства программ требуется более случайное выделение и освобождение памяти, отведенной для динамических переменных. Процедуры Dispose и FreeMem позволяют в любой момент освободить память, выделенную для любой динамической переменной.
Когда с помощью процедур Dispose и FreeMem освобождается память, отведенная для динамической переменной, не являющейся «самой верхней» переменной в динамически распределенной области, то динамически распределяемая область становится фрагментированной. Если выполнялась та же последовательность операторов. Тогда после выполнения процедуры Dispose(Ptr3) в центре динамически распределенной области образуется незанятое пространство («дыра»).
Если в данный момент выполняется процедура New(Ptr3), то это опять приведет к выделению той же области памяти. С другой стороны, выполнение процедуры Dispose(Ptr4) увеличит размер свободного блока, так как Ptr3 и Ptr4 были соседними блоками.
В конечном итоге выполнение процедуры Dispose(Ptr5) приведет сначала к созданию незанятого блока большого размера, а затем HeapPtr переместится в младшие адреса памяти. Поскольку последним допустимым указателем теперь будет Ptr2, то это приведет к действительному освобождению памяти.
Ptr1
Ptr2
HeapPtr
Младшие адреса памяти
Старшие адреса памяти
Содержимое Ptr1
Содержимое Ptr2
Теперь динамически распределяемая память находится в том же самом состоянии, в каком она находилась после выполнения процедуры Release(P). Однако создаваемые и освобождаемые при таком процессе незанятые блоки отслеживаются для их возможного повторного использования.