Фрагментация памяти
Указатели и их использование для работы с динамическими переменными.
Динамические структуры данных
V. Структуры и организация данных
ТЕХНОЛОГИЯ ПРОГРАММИРОВАНИЯ (PASCAL)
Тема:
Чередование обращений к процедурам выделения и освобождения динамической памяти в программе обычно приводит к фрагментации памяти, поэтому все операции с кучей выполняются под управлением специальной подпрограммы, называемой администратором кучи, которая автоматически пристыковывается к программе компоновщиком PASCAL и ведет учет всех свободных фрагментов в куче. Если при очередном обращении к процедуре выделения памяти эта подпрограмма находит наименьший свободный фрагмент, в котором может разместиться требуемая переменная, то адрес начала найденного фрагмента возвращается в указатель, а сам фрагмент или его часть необходимой длины помечается как занятая часть кучи. Если для требуемой переменной необходимо больше места, чем имеющиеся в свободных фрагментах, то она размещается обычным образом, начиная с адреса, находящегося в указателе HeapPtr, и, соответственно, значение HeapPtr изменяется на количество байтов, необходимое для размещения требуемой переменной.
|
|
Для освобождения целого фрагмента динамической памяти (занятого несколькими данными) перед началом выделения памяти, т. е. до применения процедур New или GetMem, в указателе запоминается текущее значение HeapPtr с помощью процедуры
Mark(<идентификатор_указателя>);
Для освобождения фрагмента кучи, начиная с адреса, который запомнила процедура Mark, и до конца динамической памяти, определена процедура
Release(<идентификатор_указателя>);
Var
P: Pointer;
P1, P2: ^integer;
begin
Mark(P);
GetMem(P1,2);
New(P2);
…
Release(P);
end.
Под действием процедуры Release переменной HeapPtr присваивается значение указателя P, а участок динамической памяти от значения указателя P до предшествующего значения переменной HeapPtr возвращается в неиспользованную динамическую память; все указатели, связанные с освобождаемым участком динамической памяти, теряют свои значения.
Вызов Release уничтожает список свободных фрагментов в куче, которые могли быть созданы до этого процедурами Dispose или FreeMem, поэтому не следует использовать одновременно механизм освобождения памяти с помощью процедур FreeMem или Dispose и Release.
Отслеживание за использованием динамической памяти, для чего определены следующие функции:
1. функция MaxAvail, тип результата которой – LongInt; она возвращает размер в байтах самого большого свободного участка динамической памяти, который находится как максимальное значение из размера неиспользованной части кучи и размеров участков, освобождённых к данному моменту.
K:=MaxAvail;
2. функция MemAvail, тип результата которой – LongInt; она возвращает суммарный размер в байтах всех свободных участков динамической памяти – и освобождённых, и ещё не использованных.
K:=MemAvail;