Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
шпоры ОС1.doc
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
1.61 Mб
Скачать

36. Работа с кучами процессов

Вся выделенная память в ОС Windows как и в другой ОС делится на 3 типа:

  • Код

  • Стек

  • Куча

Код создается отображением сегмента кода на адресное пространство процесса. Стек используется для локальных переменных и при необходимости растет блоками по 64 Кб. Выделение памяти для стека происходит автоматически и для процесса протекает незаметно. В куче процесса находятся глобальные переменные и динамически выделяемая память.

При создании процесса ОС создает в его адресном пространстве стандартную кучу процессов и ее зарезервированный размер – 1 Мб. Если память заканчивается, то к ней добавляется требуемое количество блоков размером 64 Кб.

Функция получения дескриптора на кучу: HANDLE GetProcessHeap();

Память выделяется из кучи с использованием вызовов:

LPVOID HeapAlloc(

HANDLE hHeap,

DWORD dwFlags,

SIZE_T dwBytes);

LPVOID HeapReAlloc(

HANDLE hHeap,

DWORD dwFlags,

LPVOID lpMem,

SIZE_T dwBytes);

Для освобождения памяти используется функция:

BOOL HeapFree(

HANDLE hHeap,

DWORD dwFlags,

LPVOID lpMem);

hHeap – дескриптор кучи.

lpMem – указатель уже на выделенную область памяти.

dwFlags:

HEAP_NO_SERIALIZE – отключает критический ресурс для кучи.

При компиляции программы программист обязан указать будет ли несколько нитей в его программе, для чего используется ключ компилятора _MT (если несколько нитей). При использовании этого ключа компилятор подключает в программу библиотеки работы с памятью, которые не используют флаг HEAP_NO_SERIALIZE.

Помимо основной кучи процессов можно создавать дополнительные кучи с помощью функции:

HANDLE HeapCreate(

DWORD flOptions,

SIZE_T dwInitialSize,

SIEZE_T dwMaximumSize);

dwInitialSize – начальный размер блока памяти.

dwMaximumSize – максимальный размер выделяемой области памяти, если 0 – то размер не ограничен.

flOptions:

HEAP_GENERATE_EXCEPTIONS – если флага нет функция HeapAlloc вернет NULL, если есть вызов исключения.

HEAP_NO_SERIALIZE – отключает критический ресурс для кучи.

Куча удаляется с помощью функции:

BOOL HeapDestroy(

HANDLE hHeap);

Использование нескольких куч позволяет ускорить и упростить работу с памятью.

Пример:

1. Имеется некоторая задача, в процессе решения которой будем использовать память. До try создаем новую кучу, в finally уничтожаем. При уничтожении кучи, уничтожается вся память, выделенная в ней.

2. Создаем класс, который будет работать со списком. В случае использования переменных одинакового размера (элементы списка) можно добиться нулевой фрагментации. Для этого, необходимо создать для хранения таких переменных отдельную кучу.

Физическая организация куч

При создании и росте кучи используется функция VirtualAlloc с гранулярностью 64 Кб. Функции HeapAlloc и HeapFree реализованы внутри библиотеки kernel32.dll вместе с менеджером кучи. Если памяти достаточно, то менеджер кучи выделяет память из имеющегося резерва и обращение к ядру ОС не происходит. Мелкие выделения памяти идут в адресном пространстве процесса, ускоряя выполнение программы.

Библиотечные функции malloc и free реализованы как надстройки к функциям HeapAlloc и HeapFree соответственно.

Операторы языка C++ new и delete реализованы как надстройки к функциям malloc и free соответственно.

Для проверки наличия выделенной памяти по заданному адресу имеется группа функций:

IsBadCodePtr

IsBadReadPtr

IsBadStringPtr

IsBadWritePtr