Я понимаю, как распределить кучу окна и стек кучи и т.д. Хотя я новичок в Linux, у меня нет большей ясности, как это работает?
В Windows:
Наши библиотеки DLL и exe ссылаются на многопоточные статические библиотеки CRT. Каждая DLL и exe, которую мы создаем, имеют свою собственную кучу, то есть _crtheap. Выделения и отчисления должны произойти из соответствующей кучи. То, что динамически выделяется из DLL, не может быть выделено из исполняемого файла и наоборот.
Компиляция нашего кода в DLL и exes с использованием /MD или /MDd для использования многопоточной и DLL-специфичной версии библиотеки времени выполнения свяжет как DLL, так и exe с той же библиотекой времени выполнения C и, следовательно, с одним _crtheap. Выделения всегда сопряжены с де-распределениями в одном модуле.
Это то же самое поведение на Liunx? Какие там кучи? Что относительно кучи CRT?
Я действительно не знаю, как ответить на это, но я попытаюсь дать достаточно общей информации, что я буду бить то, что вам нужно знать.
Как человек unix, то, что я узнал об управлении памятью Windows из вашего вопроса, заключается в том, что вы, ребята, много используете слово "куча". Мы этого не делаем, кроме как неофициальный синоним для "области памяти, управляемой malloc".
Есть два основных динамических элемента распределения памяти, о которых нужно знать: brk
и mmap
. Все остальные функции распределения, включая malloc
, строятся поверх них.
brk
- старый. Он работает, просто добавляя больше памяти к карте виртуальной памяти процесса после окончания сегмента bss. Вы передаете значение " brk
, и это становится "разрывом" процесса - окончанием выделенной виртуальной памяти.
malloc может быть построен поверх brk
, вызывая его с новым, более высоким значением, каждый раз, когда требуется больше памяти, и поддерживая некоторую внутреннюю структуру данных, которая отслеживает, что было освобождено и что еще используется. (Возвращение памяти обратно в систему бесплатно не было сделано в классической реализации.) Внутренняя структура данных некоторой реализации malloc должна была быть кучей, давая сегменту brk его псевдоним: "куча".
См. Также: Что делает системный вызов brk()? (у него есть фотографии!)
Это действительно необычно для программы, чтобы напрямую вызвать brk
. (Или даже тонкую обертку sbrk
). Каждое использование brk
в обычной программе осуществляется через malloc
. Помните, что хотя вы просматриваете библиотеку C, в том числе malloc
, как дополнительную опцию, у нас есть OS, которая тесно связана с C, поэтому программа, которая не использует libc для низкоуровневых материалов, таких как управление памятью, очень Действительно. Поэтому большую часть времени все память в сегменте brk, ака "куча" управляется malloc. Однако обратное неверно, потому что...
mmap
, новее, чем brk
(mmap с 90-х годов, brk - с 70-х годов) предлагает множество вариантов. Если вы хотите отобразить файл в память или выделить несколько несмежных блоков памяти вместо того, чтобы просто добавить некоторое пространство в конце исходного блока данных, вы используете mmap
. Погружаемый библиотечный загрузчик использует mmap для сопоставления каждого текста библиотеки и данных. Современные реализации malloc используют mmap для больших запросов и brk для небольших. У нас также есть mremap
который переносит сопоставление на новый виртуальный адрес, сохраняя при этом один и тот же физический адрес, позволяя realloc избежать дорогостоящей копии.
Если вы посмотрите на /proc/$PID/maps
в Linux, вы увидите область памяти с надписью [heap]
. Это сегмент brk. Там только один из этих процессов. (Я видел несколько примеров, в которых файл maps
показывал 2 из них, но они были непрерывными и имели одинаковые атрибуты, поэтому они действительно эквивалентны одному региону. Я не знаю, что вызывает двойной листинг.)
С учетом всего этого, что бы это значило, чтобы выделить "лишнюю кучу"? Вы можете запросить некоторую память из системы с помощью mmap, предоставив вам регион, который не зависит от malloc. Затем вы можете сделать свое собственное malloc-подобное управление этим регионом, раздавая его кусками разных размеров и отслеживая, какие части не используются. Но ваш новый распределитель не будет "кучей". Что на самом деле ничего не значит, потому что система ничего не знает о кучах.