Управление кучей

Я знаю, что есть метаданные, которые хранят вспомогательную информацию, которая используется во время free(), realloc() когда мы поставляем только указатель.

У меня мало сомнений по поводу кучи.

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

  • Как будет сохраняться куча информации? Я думаю, механизм хеширования. Я погуглил и попробовал ТАК тоже. большинство из них объяснили это как конкретную реализацию.. как то так.

3 ответа

Решение

Куча, как и стек, представляет собой отдельный процесс и (почти) является чисто пользовательским пространством.

Менеджер кучи использует sbrk Системный вызов информирует операционную систему о том, что она намерена увеличить объем необходимой памяти. Это мало чем отличается от изменения диапазона страниц с "неизвестного" на "существующий, ноль, к которому никогда не обращались" (в действительности это означает, что они все еще не существуют, но ОС притворяется, что они это делают). При первом доступе к странице происходит сбой, и ОС извлекает нулевую страницу из пула нулей.
(Это может быть немного сложнее, так как менеджер кучи может также уменьшить сегмент данных, если много памяти было освобождено сверху, но в основном это так просто).

Это уже все, что ОС знает о куче. Все остальное, например, разбиение блоков, помещение освобожденных блоков в список или аналогичную структуру и повторное использование блоков, происходит внутри диспетчера кучи, которая прямо или косвенно (например, как часть glibc) является частью вашей программы.

Что именно делает менеджер кучи, зависит от реализации, существует по крайней мере полдюжины известных различных реализаций malloc, которые работают по-разному. Посмотрите, например, этот или этот или этот.

Стек работает таким же или похожим образом. Определенный диапазон памяти изначально "зарезервирован", фактически ничего не резервируя (то есть без создания страниц). Несколько страниц фиксируются (то есть создаются), а последняя страница либо защищена от записи, либо не существует, и это запоминается особым образом. Когда стек увеличивается так, что эта последняя страница затрагивается, происходит сбой. Затем новая страница извлекается из нулевого пула, при условии, что стек все еще находится в допустимых пределах.

Когда процесс завершается, все ссылки на эти страницы удаляются и (при условии, что они не передаются другому процессу, который все еще содержит ссылку) передаются фоновой задаче с низким приоритетом, которая обнуляет их и добавляет их в "нулевой пул".

Да, куча также для каждого процесса.

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

Прочитайте это, оно немного старое ('07), но имеет соответствующие детали, изложенные Дэймоном

http://www.blackhat.com/presentations/bh-usa-07/Ferguson/Whitepaper/bh-usa-07-ferguson-WP.pdf

Другие вопросы по тегам