TURBO PASCAL

Новости

Программы   

Turbo Pascal 

Игры

Документация   

Странности

FAQ

Ссылки

Форум

Гостевая книга

Рассылка

Благодарности

Об авторе

 

 

Список свободных блоков 

             Адреса и размеры свободных блоков,  созданных при  операциях
        Dispose  и FrееМем,  хранятся в списке свободных блоков,  который
        увеличивается вниз, начиная со старших адресов памяти, в сегменте
        динамически  распределяемой области.  Каждый раз перед выделением
        памяти для динамической переменной,  перед тем,  как  динамически
        распределяемая  область будет расширена,  проверяется список сво-
        бодных блоков.  Если имеется блок  соответствующего  размера  (то
        есть размер которого больше или равен требуемому размеру),  то он
        используется.

             Процедура Rеlеаsе всегда очищает  список  свободных  блоков.
        Таким образом,  программа динамического распределения памяти "за-
        бывает" о незанятых блоках,  которые могут существовать ниже ука-
        зателя динамически распределяемой области.  Если вы чередуете об-
        ращения к процедурам Маrk и Rеlеаsе с  обращениями  к  процедурам
        Dispose и FrееМем, то нужно обеспечить отсутствие таких свободных
        блоков.

             Переменная FreeList модуля System указывает на  первый  сво-
        бодный  блок  динамически  распределяемой области памяти.  Данный
        блок содержит указатель на следующий свободный блок и  т.д.  Пос-
        ледний  свободный  блок содержит указатель на вершину динамически
        распределяемой области (то есть адрес,  заданный  HeapPtr).  Если
        свободных блоков в списке свободных блоков нет, то FreeList будет
        равно HeapPtr.

             Формат первых  8  байт  свободного  блока   задается   типом
        TFreeRec:
            type
               PFreeRec = ^TFreeRec;
               TFreeRec = record
                              Next: PFreeRec;
                              Size: Pointer;
                          end;

             Поле Next указывает на следующий свободный блок,  или на  ту
        же ячейку,  что и HeapPtr, если блок является последним свободным
        блоком.  В поле Size записан размер свободного блока.  Значение в
        поле  Size  представляет собой не обычное 32-битовое значение,  а
        "нормализованное" значение-указатель с числом свободных  парагра-
        фов  (16-байтовых  блоков)  в старшем слове и счетчиком свободных
        байт (от 0 до 15) в младшем слове.  Следующая  функция  BlockSize
        преобразует значение поля Size в обычное значение типа Longint:

            function BlockSize(Size: Pointer): Longint;
            type
               PtrRec = record Lo, Hi: Word end;
            begin
               BlockSize := Longint(PtrRec(Size)).Hi)*16+PtrRec(Size).Lo
            end;

            Чтобы обеспечить, что в начале свободного блока всегда имеет-
        ся место для TFreePtr,  подсистема управления динамически распре-
        деляемой областью памяти округляет размер каждого блока, выделен-
        ного подпрограммами New и GetMem  до  8-байтовой  границы.  Таким
        образом,  8  байт выделяется для блоков размером 1..8,  16 байт -
        для блоков размером 9..16 и т.д. Сначала это кажется непроизводи-
        тельной тратой памяти.  Это в самом деле так, если бы каждый блок
        был размером 1 байт. Но обычно блоки имеют больший размер, поэто-
        му относительный размер неиспользуемого пространства меньше.

              8-байтовый коэффициент  раздробленности  обеспечивает,  что
        при большом числе случайного выделения и освобождения блоков  от-
        носительно небольшого размера (что типично для записей переменной
        длины в программах обработки текста) не приведет к сильной  фраг-
        ментации  динамически распределяемой области.  В качестве примера
        предположим,  что занимается и  освобождается  блок  размером  50
        байт.  После  его  освобождения  запись о нем включается в список
        свободных блоков.  Этот блок округляется до 56 (7*8) байт. Если в
        дальнейшем потребуется блок размером от 49 до 56 байт,  то данный
        блок будет полностью повторно использован, а не останется от 1 до
        7 байт памяти (использование который маловероятно), которые будут
        только фрагментировать динамически распределяемую область.

Содержание

На первую страницу

Rambler's Top100 Rambler's Top100
PROext: Top 1000

(с)Все права защищены

По всем интересующим вопросам прошу писать на электронный адрес

Hosted by uCoz