Администратор динамически распределяемой области памяти
Windows поддерживает динамическое распределение памяти в
двух различных динамически распределяемых областях: глобальной
динамически распределяемой области и локальной динамически расп-
ределяемой области.
Примечание: Более подробно о локальной и глобальной
динамически распределяемой области рассказывается в "Руко-
водстве программиста по Windows".
Глобальная динамически распределяемая область - это пул па-
мяти, доступный для всех прикладных программ. Хотя могут выде-
ляться блоки глобальной памяти любого размера, глобальная динами-
чески распределяемая область памяти предназначена только для
"больших" областей памяти (256 байт или более). Каждый блок гло-
бальной памяти имеет избыточный размер 20 байт, и при работе в
стандартной среде Windows в улучшенном режиме 386 существует ог-
B.Pascal 7 & Objects/LR - 369 -
раничение в 8192 блока памяти, только некоторые из которых дос-
тупны для отдельной прикладной программы.
Локальная динамически распределяемая область памяти - это
пул памяти, доступной только для вашей прикладной программы или
библиотеки. Она расположена в верхней части сегмента данных прик-
ладной программы или библиотеки. Общий размер блоков локальной
памяти, которые могут выделяться в локальной динамически распре-
деляемой области, равен 64К, минус размер стека прикладной прог-
раммы и статических данных. По этой причине локальная динамически
распределяемая область памяти лучше подходит для "небольших" бло-
ков памяти (26 байт или менее). По умолчанию размер локальной ди-
намически распределяемой области равен 8К, но с помощью директивы
компилятора $M это значение можно изменить.
Примечание: Borland Pascal не поддерживает механизм
распределения памяти с помощью процедур Mark и Release, ко-
торые предусмотрены в версии для DOS.
Borland Pascal включает в себя подсистему управления динами-
чески распределяемой памятью (администратор памяти), которая реа-
лизует стандартные процедуры New, Dispose, GetMem и FreeMem. Для
всех выделений памяти подсистема динамически управления распреде-
ляемой областью памяти использует глобальную динамически распре-
деляемую область. Поскольку глобальная динамически распределяемая
область памяти имеет системное ограничение в 8192 блока (что оп-
ределенно меньше, чем может потребоваться в некоторых прикладных
задачах), подсистема управления динамически распределяемой об-
ластью памяти Borland Pascal для улучшения производительности и
обеспечения выделения существенно большего числа блоков включает
в себя алгоритм вторичного распределения сегмента.
Примечание: Более подробно об этом рассказывается в
Главе 11 "Динамически компонуемые библиотеки".
Алгоритм вторичного выделения сегмента работает следующим
образом: при распределении большого блока администратор динами-
чески распределяемой области памяти просто выделяет глобальный
блок памяти, используя подпрограмму Windows ClobalAlloc. При вы-
делении маленького блока администратор динамически распределяемой
области памяти выделяет больший блок памяти, а затем делит его на
более мелкие блоки (как требуется). При выделении "маленьких"
блоков перед тем, как администратор динамически распределяемой
области памяти выделит блок глобальной динамически распределяемой
памяти (который будет в свою очередь разбит на блоки), повторно
используются все доступные мелкие блоки.
Границу между маленькими и большими блоками определяется пе-
ременной HeapLimit. По умолчанию она имеет значение 1024 байта.
Переменная HeapBlock определяет размер, который использует под-
система управления динамически распределяемой областью памяти при
выделении блоков для вторичного разбиения. По умолчанию она имеет
значение 8192 байта. Изменять эти значения вам незачем, но если
B.Pascal 7 & Objects/LR - 370 -
вы решите это сделать, убедитесь что HeapBlock имеет значение по
крайней мере в четыре раза превышающее HeapLimit.
Переменная HeapAllocFlags определяет значение флагов атрибу-
тов, передаваемых GlobalAlloc, когда администратор памяти распре-
деляет глобальные блоки. В программе по умолчанию используется
значение gmem_Moveable, а в библиотеке - gmem_Moveable +
gmem_SSEShure.
Блоки глобальной памяти, выделяемые администратором динами-
чески распределяемой области памяти, всегда блокируются непос-
редственно после своего выделения (с помощью GlobalLock) немед-
ленно после своего выделения и не разблокируются, пока не будут
освобождены. Этим обеспечивается, что селекторы (адреса сегмен-
тов) блоков не изменяются. В стандартной среде Windows и улучшен-
ных режимах процессора 386 фиксированные блоки могут, тем не ме-
нее, перемещаться в физической памяти, освобождая место для дру-
гих запросов по выделению памяти, поэтому это не ухудшает произ-
водительности администратора динамически распределяемой области
памяти Borland Pascal. Однако в реальном режиме, если от Windows
требуется расширение локальной динамически распределяемой облас-
ти, администратор памяти Windows, возможно, не сможет переместить
их, чтобы выделить другие блоки. Если ваша прикладная программа
использует локальную динамически распределяемую область и должна
выполняться в реальном режиме, можно рассмотреть при выделении
блоков динамической памяти возможность использования средств
распределения памяти, предоставляемых Windows.