TURBO PASCAL

Новости

Программы   

Turbo Pascal 

Игры

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

Странности

FAQ

Ссылки

Форум

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

Рассылка

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

Об авторе

 

 

Управление памятью 

             При разработке программ,  работающих с динамической памятью,
        обычно используются стандартные процедуры New,  Dispose, GetMem и
        FreeMem. Однако получить доступ к администратору памяти  защищен-
        ного  режима Borland вы можете с помощью функций GlobalXXXX в мо-
        дуле WinAPI.

             Заметим, что функции GlobalXXXXPtr комбинируют в одной подп-
        рограмме общие  последовательности  вызовов  функций,  такие  как
        GlobalAlloc,  за которыми следуют вызовы GlobalLock, GlobalUnlock
        или GlobalFree.

                       Подпрограммы управления памятью API
                                                            Таблица 17.2
        ┌─────────────────────┬─────────────────────────────────────────┐
        │    Функция          │                 Описание                │
        ├─────────────────────┼─────────────────────────────────────────┤
        │   GetFreeSpace      │ Определяет объем свободной памяти  в ди-│
        │                     │ намически распределяемой области.       │
        ├─────────────────────┼─────────────────────────────────────────┤
        │   GlobalAlloc       │ Выделяет блок памяти в динамически расп-│
        │                     │ ределяемой области.                     │
        ├─────────────────────┼─────────────────────────────────────────┤
        │   GlobalAllocPtr    │ Выделяет и блокирует блок памяти (с  по-│
        │                     │ мощью вызовов GlobalAlloc и GlobalLock).│
        │                     │                                         │
        ├─────────────────────┼─────────────────────────────────────────┤
        │   GlobalCompact     │ Переупорядочивает  память,  распределен-│
        │                     │ ную в динамической области,  так что ос-│
        │                     │ вобождается заданный объем памяти.      │
        ├─────────────────────┼─────────────────────────────────────────┤
        │   GlobalDiscard     │ Выгружает заданный объект памяти.       │
        ├─────────────────────┼─────────────────────────────────────────┤
        │   GlobalDosAlloc    │ Распределяет память, к которой можно по-│
        │                     │ лучить доступ в реальном режиме DOS. Эта│
        │                     │ память будет существовать в первом мега-│
        │                     │ байте линейного адресного пространства. │
        ├─────────────────────┼─────────────────────────────────────────┤
        │   GlobalDosFree     │ Освобождает память, выделенную  ранее  с│
        │                     │ помощью GlobalDosAlloc.                 │
        ├─────────────────────┼─────────────────────────────────────────┤
        │   GlobalFlags       │ Получает информацию о блоке памяти.     │
        ├─────────────────────┼─────────────────────────────────────────┤
        │   GlobalFree        │ Освобождает разблокированный блок памяти│
        │                     │ и делает его описатель недействительным.│
        ├─────────────────────┼─────────────────────────────────────────┤
        │   GlobalFreePtr     │ Разблокирует и освобождает  блок  памяти│
        │                     │ с помощью GlobalUnlock и GlobalFree.    │
        ├─────────────────────┼─────────────────────────────────────────┤
        │   GlobalHandle      │ Получает описатель объекта в  памяти  по│
        │                     │ заданному адресу сегмента.              │
        ├─────────────────────┼─────────────────────────────────────────┤
        │   GlobalLock        │ Увеличивает счетчик ссылки блока  памяти│
        │                     │ и возвращает указатель на него.         │
        ├─────────────────────┼─────────────────────────────────────────┤
        │   GlobalLockPtr     │ То же, что и GlobalLock, но вместо  опи-│
        │                     │ сателя воспринимает указатель.          │
        ├─────────────────────┼─────────────────────────────────────────┤
        │   GlobalLRUNewest   │ Перемещает объект в памяти на новую  не-│
        │                     │ давно используемую позицию, минимизируя,│
        │                     │ таким   образом,   вероятность  выгрузки│
        │                     │ объекта.                                │
        ├─────────────────────┼─────────────────────────────────────────┤
        │   GlobalLRUOldest   │ Перемещает  объект  в  памяти  на  самую│
        │                     │ "старую" недавно  используемую  позицию,│
        │                     │ максимизирую вероятность  выгрузки  объ-│
        │                     │ екта.                                   │
        ├─────────────────────┼─────────────────────────────────────────┤
        │   GlobalNorify      │ Вызывает адрес экземпляра процедуры уве-│
        │                     │ домления, передавая описатель блока, ко-│
        │                     │ торый нужно выгрузить.                  │
        ├─────────────────────┼─────────────────────────────────────────┤
        │   GlobalPageLock    │ Увеличивает значение счетчика  блокиров-│
        │                     │ ки для памяти, связанной с данным селек-│
        │                     │ тором.                                  │
        ├─────────────────────┼─────────────────────────────────────────┤
        │   GlobalPageUnlock  │ Уменьшает значение  счетчика  блокировки│
        │                     │ для памяти,  связанной с данным селекто-│
        │                     │ ром.                                    │
        ├─────────────────────┼─────────────────────────────────────────┤
        │   GlobalPtrHandle   │ По заданному указателю  на  блок  памяти│
        │                     │ возвращает описатель этого блока.       │
        ├─────────────────────┼─────────────────────────────────────────┤
        │   GlobalReAlloc     │ Перераспределяет блок памяти.           │
        ├─────────────────────┼─────────────────────────────────────────┤
        │   GlobalReAllocPtr  │ Разблокирует, перераспределяет и  блоки-│
        │                     │ рует блок   памяти   (используя  функции│
        │                     │ GlobalUnlock,      GlobalReAlloc       и│
        │                     │ GlobalLock).                            │
        ├─────────────────────┼─────────────────────────────────────────┤
        │   GlobalSize        │ Определяет текущий размер блока памяти. │
        ├─────────────────────┼─────────────────────────────────────────┤
        │   GlobalUnfix       │ Разблокирует блок памяти,  блокированный│
        │                     │ ранее с помощью GlobalLock.             │
        ├─────────────────────┼─────────────────────────────────────────┤
        │   GlobalUnockPtr    │ То же,  что и  GlobalUnlock,  но  вместо│
        │                     │ описателя воспринимает указатель.       │
        ├─────────────────────┼─────────────────────────────────────────┤
        │   LockSegment       │ Блокирует заданный выгружаемый сегмент. │
        ├─────────────────────┼─────────────────────────────────────────┤
        │   UnlockSegment     │ Разблокирует сегмент.                   │
        └─────────────────────┴─────────────────────────────────────────┘

             Функция GlobalAlloc используется  для  распределения  блоков
        памяти. Для их освобождения применяется функция GlobalFree. Адми-
        нистратор памяти поддерживает три типа блоков памяти: фиксирован-
        ный, перемещаемый  и  выгружаемый.  Фиксированный блок остается в
        одних и тех же адресах физической памяти. Перемещаемый блок может
        перемещаться в  физической  памяти и освобождать место для других
        запросов на выделение памяти,  а выгружаемые блоки  могут  выгру-
        жаться из памяти,  освобождая место для других блоков.  С помощью
        передаваемых GlobalAlloc флагов вы можете выбрать  один  из  этих
        трех типов:

             * gmem_Fixed                          (фиксированный)
             * gmem_Moveable                       (перемещаемый)
             * gmem_Moveable + gmem_Discardable    (выгружаемый)

             Прикладная программа  обычно  выделяет  только  перемещаемые
        блоки памяти,  которые  представляются  типом  THandle  в  модуле
        WinAPI. Описатель памяти - это значение размером в слово, которое
        идентифицирует блок памяти аналогично тому, как описатель файла -
        это значение размером в слово, идентифицирующее открытый файл.

             Перед тем как вы сможете получить доступ к памяти, его нужно
        заблокировать с помощью функции GlobalAlloc, а когда вы закончите
        к нему  обращаться,  его  нужно  разблокировать с помощью функции
        GlobalUnlock. GlobalLock возвращает полный 32-разрядный указатель
        на первый байт блока.  Смещение указателя всегда равно 0. В защи-
        щенном режиме DOS селектор указателя - это тоже самое, что описа-
        тель блока, но в Windows это не всегда так.

             Правильная последовательность вызовов для выделения,  блоки-
        ровки, разблокировки или освобождения блока показана в  приведен-
        ном ниже  примере.  В  данном  примере  H  -  это переменная типа
        THandle, а P - указатель:

             H := GlobalAlloc(gmem_Moveable, 8192);   { выделение блока }
             if H <> then                        { если память выделена }
             begin
                P := GlobalLock(H);                  { блокировка блока }
                    .
                    .                          { доступ к блоку через P }
                    .
                GlobalUnlock(H);                  { разблокировать блок }
                GlobalFree(H);                        { освободить блок }
             end;

             Блокировка и разблокировка блока при каждом обращении к нему
        достаточно утомительна и ведет к ошибкам, и реально она необходи-
        ма только  для  выгружаемых  блоков  и  в  прикладных  программах
        Windows, работающих в реальном режиме.  Во всех других  ситуациях
        лучшим решением является блокировка блока сразу после его выделе-
        ния и сохранение этого состояния до освобождения  блока.  С  этой
        целью модуль WinAPI включает в себя семейство подпрограмм-"оболо-
        чек" GlobalXXXXPtr.   Особый   интерес    представляет    функция
        GlobalAllocPtr, которая выделяет и блокирует блок памяти, и функ-
        ция GlobalFreePtr,  разблокирующая и освобождающая блок памяти. С
        помощью этих подпрограмм приведенный выше пример можно упростить:

             H := GlobalAlloc(gmem_Moveable, 8192);   { выделение блока }
             if H <> then                        { если память выделена }
             begin
                    .
                    .                                  { доступ к блоку }
                    .
                GlobalFreePtr(P);                     { освободить блок }
             end;

             Вызвав функцию GlobalReAlloc,  вы можете изменить размер или
        атрибуты блока   памяти,   сохранив   его   содержимое.   Функция
        GlobalReAlloc возвращает новый описатель блока, который может от-
        личаться от  передаваемого функции описателя,  если старый размер
        или новый размер блок превышает 64К.  Заметим, что в тех случаях,
        когда старый   размер  блока  и  новый  его  размер  меньше  64К,
        GlobalReAlloc всегда может изменить размер блока,  не изменяя его
        описателя.

             Функция GlobalReAlloc можно также использоваться для измене-
        ния   атрибутов   блока.   Это  можно  сделать,  задав  наряду  с
        gmem_Moveable или gmem_Discardable флаг gmem_Modify.

             Функция GlobalReAlloc   выполняет  те  же  действия,  что  и
        GlobalReAlloc, но обе они вместо описателей использует указатели.

             Имеется также   ряд   других,   менее   часто   используемых
        GlobalXXXX. Все  они  подробно  описаны в Главе 1 ("Справочник по
        библиотеке") "Справочного руководства программиста".




Содержание

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

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

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

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

Hosted by uCoz