logo
ZH ос 20 вопр 36 стр

Кучи. Кучи в Windows nt (2000).

Куча – 3-й и последний элемент управления памятью в Win32. Используется для создания небольших блоков данных, например связанных с очередями, списками, деревьями.

В DOS и Win16 кучи играли основную роль, в Win32 – вспомогательную.

Особенности куч Win32:

Структура куч Win32:

Доп. кучи создаются с помощью HeapCreate. Используются для защиты компонентов, для более эффективного управления памятью, для локализации доступа.

Каждый блок имеет свой заголовок – арену. Заголовок кучи имеет следующую структуру. Заголовок состоит из полей.

  1. общий размер памяти, зарезервированной для кучи.

  2. указатель на следующую кучу, если она есть.

  3. указатель на начало списка дополнительных подкуч данной кучи.

  4. списки свободных блоков.

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

1-ый список состоит из блоков, размер которых меньше 20h байт.

2-ой список - меньше 80h байт.

3-ий список - меньше 200h байт.

4-ый список - меньше FFFFFFFFh байт.

Функции работы с кучей.

GetProcessHeap(…) – получить дескриптор кучи, предоставляемый процессу по умолчанию. Эта функция находит PDB и извлекает из базы данных дескриптор кучи.

HeapCreate(…) – создание кучи. Вызывают не только приложения пользователя, но и kernel32.dll и user32.dll вызывает для создания системных структур данных, например PDB или базы данных потока (TDB).

Процесс создания кучи проходит в 2 этапа: резервирование памяти для кучи и связывание кучи в списке куч процесса, инициализация всех полей заголовка кучи.

Удаление кучи.

HeapDestroy(…). Проблема состоит в том, что

  1. куча должна быть свободной, то есть CriticalSection=0.

  2. куча может иметь подкучи.

Необходимо удалить весь список связанных подкуч. то есть HeapDestroy(…) должна выполнять действия по корректировке списка.

Выделение блока памяти в определённой куче.

HeapAlloc(…). Этот процесс состоит из следующих этапов.

  1. проверки параметров функции HeapAlloc(…).

  2. захват CriticalSection заголовка кучи.

  3. выравнивание размера запрошенного блока к ближайшему числу кратному 4 и добавление размера арены.

  4. нахождение первого свободного блока в списке. Если блок найден, то функция проверяет насколько этот блок велик. Если можно поделить на 2, то создаются 2 блока, настраиваются их арены. Первый блок занят функцией HeapAlloc(…), другой поступает в список свободных блоков.

  5. освобождение критической секции. Указатель кучи устанавливается на первый байт следующего за ареной блока. Если функция не найдёт в списке подходящего свободного блока, то kernel32 создаёт подкучу, вставляет в список подкуч, а затем функция HeapAlloc(…) возвращается к поиску свободных блоков.

Освобождение блока кучи.

  1. HeapFree(…).

  2. проверка параметров.

  3. захват CriticalSection.

  4. если перед освобождаемым блоком уже есть свободный блок, то сливаются в один.

  5. фактическое освобождение блока, возврат его в кучу.

  6. освобождение CriticalSection.

Куча, предоставляемая процессу по умолчанию.

Данную кучу нельзя уничтожить (создается при создании процесса, уничтожается при завершении процесса). Данную кучу помимо пользователя используют функции Win32.