Динамическое распределение памяти в MS Windows. Габрельян Б.В. - 4 стр.

UptoLike

Составители: 

виртуальными (логическими) адресами. ОС использует файл подкачки,
позволяющий поддерживать диапазон виртуальных адресов больший, чем
диапазон физически адресуемой памяти. При нехватке физической памяти часть
страниц может быть выгружена в файл подкачки, а затем, при необходимости,
вновь загружена в ОЗУ. При повторной загрузке, в общем случае, меняются как
физический, так и виртуальный адреса
страницы, поэтому программа не может
полагаться на то, что указатель на динамически выделенный блок памяти содержит
действительный адрес ячейки ОЗУ. ОС учитывает занятые блоки памяти,
присваивая им уникальные целые положительные значения - дескрипторы. В связи
с этим техника работы с динамически распределяемой памятью в MS Windows
такова:
с помощью специальных функций MS Windows API (Application Programming
Interface - набор
функций, вызываемых приложением для запроса определенных
сервисов у ОС), но не функций malloc(), calloc() или операции new,
запрашивается блок памяти нужного размера из локальной (LockalAlloc()) или
глобальной (GlobalAlloc()) кучи. При этом функция возвращает дескриптор
блока;
всякий раз, когда необходим доступ к захваченному блоку, необходимо
зафиксировать его в памяти (т.е. зафиксировать виртуальные адреса ячеек
блока) с помощью другой функции (LocalLock() или GlobalLock()), которой
передается полученный прежде дескриптор (дескрипторы не меняются при
перемещении блоков памяти). Функция возвратит указатель, с которым теперь
можно работать так же, как и в MS DOS;
завершив операции по доступу к блоку, необходимо отменить его фиксацию
(функция LockalUnlock() или GlobalUnlock());
если блок больше не нужен -
освободить память (LockalFree() или GlobalFree()).
Несмотря на столь существенные изменения, MS Windows 3.x все еще тесно
связаны с понятием сегмента. Само разделение на локальную и глобальную кучи
связано со все тем же 16-битным смещением или полным 32-битным адресом
(сегмент:смещение). Более того, многие функции переключают процессор в
реальный режим и являются по сути MS DOS функциями. Поэтому API MS
Windows 3.x называют Win16 API.
Семейство ОС MS Windows 9x/Me и, тем более, MS Windows NT/2000/XP
поддерживают не сегментированную, "плоскую" модель памяти. Весь
(виртуальный) адрес вырождается в смещение, но это смещение 4-х байтовое (32
двоичных разряда). На текущий момент существует 64-разрядная версия MS
Windows XP, в которой адрес задается 8-ю байтами. На аппаратном уровне,
безусловно, используются регистры дескрипторов страниц, но приложение
оперирует только
с 4-х (или 8-и) байтовыми виртуальными адресами. В такой
модели уже не может быть локальной кучи. Функции LocalAlloc(), GlobalAlloc() и
т.д. поддерживаются, но, во-первых, работают они одинаково, а, во-вторых, лишь
производят обращение к другой, базовой для Win32 API функции - VirtualAlloc().
Теперь не нужно заботиться о фиксации блока в ОЗУ, т.к. виртуальные (но
не
физические) адреса ячеек блока не изменяются при любых его перемещениях,
проводимых ОС. Учет блоков по-прежнему ведется с помощью дескрипторов, но,
единожды получив указатель на блок, можно пользоваться им вплоть до удаления
виртуальными (логическими) адресами. ОС использует файл подкачки,
позволяющий поддерживать диапазон виртуальных адресов больший, чем
диапазон физически адресуемой памяти. При нехватке физической памяти часть
страниц может быть выгружена в файл подкачки, а затем, при необходимости,
вновь загружена в ОЗУ. При повторной загрузке, в общем случае, меняются как
физический, так и виртуальный адреса страницы, поэтому программа не может
полагаться на то, что указатель на динамически выделенный блок памяти содержит
действительный адрес ячейки ОЗУ. ОС учитывает занятые блоки памяти,
присваивая им уникальные целые положительные значения - дескрипторы. В связи
с этим техника работы с динамически распределяемой памятью в MS Windows
такова:
• с помощью специальных функций MS Windows API (Application Programming
    Interface - набор функций, вызываемых приложением для запроса определенных
    сервисов у ОС), но не функций malloc(), calloc() или операции new,
    запрашивается блок памяти нужного размера из локальной (LockalAlloc()) или
    глобальной (GlobalAlloc()) кучи. При этом функция возвращает дескриптор
    блока;
• всякий раз, когда необходим доступ к захваченному блоку, необходимо
    зафиксировать его в памяти (т.е. зафиксировать виртуальные адреса ячеек
    блока) с помощью другой функции (LocalLock() или GlobalLock()), которой
    передается полученный прежде дескриптор (дескрипторы не меняются при
    перемещении блоков памяти). Функция возвратит указатель, с которым теперь
    можно работать так же, как и в MS DOS;
• завершив операции по доступу к блоку, необходимо отменить его фиксацию
    (функция LockalUnlock() или GlobalUnlock());
• если блок больше не нужен - освободить память (LockalFree() или GlobalFree()).
    Несмотря на столь существенные изменения, MS Windows 3.x все еще тесно
связаны с понятием сегмента. Само разделение на локальную и глобальную кучи
связано со все тем же 16-битным смещением или полным 32-битным адресом
(сегмент:смещение). Более того, многие функции переключают процессор в
реальный режим и являются по сути MS DOS функциями. Поэтому API MS
Windows 3.x называют Win16 API.
    Семейство ОС MS Windows 9x/Me и, тем более, MS Windows NT/2000/XP
поддерживают не сегментированную, "плоскую" модель памяти. Весь
(виртуальный) адрес вырождается в смещение, но это смещение 4-х байтовое (32
двоичных разряда). На текущий момент существует 64-разрядная версия MS
Windows XP, в которой адрес задается 8-ю байтами. На аппаратном уровне,
безусловно, используются регистры дескрипторов страниц, но приложение
оперирует только с 4-х (или 8-и) байтовыми виртуальными адресами. В такой
модели уже не может быть локальной кучи. Функции LocalAlloc(), GlobalAlloc() и
т.д. поддерживаются, но, во-первых, работают они одинаково, а, во-вторых, лишь
производят обращение к другой, базовой для Win32 API функции - VirtualAlloc().
Теперь не нужно заботиться о фиксации блока в ОЗУ, т.к. виртуальные (но не
физические) адреса ячеек блока не изменяются при любых его перемещениях,
проводимых ОС. Учет блоков по-прежнему ведется с помощью дескрипторов, но,
единожды получив указатель на блок, можно пользоваться им вплоть до удаления