Модуль «System». Константы. Переменные. Стандартные процедуры и функции, страница 5

        Когда с помощью процедур Dispose и FrееМем освобождается память,  отведенная для динамической переменной, не являющаяся "самой верхней" переменной в динамически распределяемой  области, то динамически  распределяемая область становится фрагментированной. Предположим, что выполнялась та же последовательности операторов, что  и  в  предыдущем  примере.  Тогда после выполнения процедуры Dispose(Ptr3) в центре динамически распределяемой  области памяти образуется незанятое пространство ("дыра").  Это показано на Рис. 4.
 
          HeapEnd   -->--------------------------- Верхняя граница
                       ¦                          ¦ памяти
                       ¦                          ¦
          HeapPtr   -->+--------------------------+
                       ¦   содержимое Ptr5^       ¦
              Ptr5  -->+--------------------------+
                       ¦   содержимое Ptr4^       ¦
              Ptr4  -->+--------------------------+
                       ¦--------------------------¦
                       ¦--------------------------¦
                       +--------------------------+
                       ¦   содержимое Ptr2^       ¦
              Ptr2  -->+--------------------------+
                       ¦   содержимое Ptr1^       ¦
              Ptr1  -->L--------------------------- Нижняя граница памяти
Рис. 4 Создание незанятой области ("дыры")  в динамически распределяемой области памяти.
 
        Если в данный момент выполняется процедура New(Ptr3), то это опять приведет к выделению той же области памяти. С другой стороны, выполнение процедуры Dispose(Ptr4) увеличит размер свободного блока,  так как Ptr3 и Ptr4  были  соседними  блоками  (см.  Рис. 5).
 
          HeapEnd   -->--------------------------- Верхняя граница
                       ¦                          ¦ памяти
                       ¦                          ¦
          HeapPtr   -->+--------------------------+
                       ¦   содержимое Ptr5^       ¦
              Ptr5  -->+--------------------------+
                       ¦--------------------------¦
                       ¦--------------------------¦
                       ¦--------------------------¦
                       ¦--------------------------¦
                       +--------------------------+
                       ¦   содержимое Ptr2^       ¦
              Ptr2  -->+--------------------------+
                       ¦   содержимое Ptr1^       ¦
              Ptr1  -->L--------------------------- Нижняя граница памяти
Рис. 5 Увеличение размера незанятого блока памяти.
 
        В конечном итоге выполнение процедуры Dispose(Ptr5) приведет сначала  к  созданию  незанятого блока большего размера,  а затем НеаpPtr переместится в более  младшие  адреса  памяти.  Поскольку последним  допустимым  указателем  теперь  будет  Ptr2 (см.  Рис. 6),  то это приведет к действительному освобождению незанятого блока.
          HeapEnd   -->--------------------------- Верхняя граница
                       ¦                          ¦ памяти
                       ¦                          ¦
                       ¦                          ¦
                       ¦                          ¦
                       ¦                          ¦
                       ¦                          ¦
                       ¦                          ¦
                       ¦                          ¦
          HeapPtr   -->+--------------------------+
                       ¦   содержимое Ptr2^       ¦
              Ptr2  -->+--------------------------+
                       ¦   содержимое Ptr1^       ¦
              Ptr1  -->L--------------------------- Нижняя граница памяти
Рис. 7 Освобождение незанятого блока памяти.