Как управляется, реализуется, распределяется память кучи и стека

Возможные дубликаты:
Как управляется, реализуется, распределяется память кучи и стека?
Стек, Static и Heap в C ++

В C / C ++ мы можем хранить переменные, функции, функции-члены, экземпляры класса либо в стеке, либо в куче.

Как каждый реализован? Как это делается (высокий уровень)? Выделяет ли gcc предварительно часть памяти, которая будет использоваться для стека и кучи, а затем распределяет ее по запросу? Исходная память поступает из ОЗУ?

Можно ли разместить функцию в куче, а не в стеке?

             --Clarification--

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


person Community    schedule 31.07.2009    source источник
comment
Точный дубликат закрытого вопроса: stackoverflow.com/questions/1212797/   -  person Pete    schedule 31.07.2009
comment
Пожалуйста, не делайте репост, когда люди закрывают ваш вопрос как дубликат (и я проголосовал за повторное открытие вашего другого вопроса, но я собираюсь проголосовать за то, чтобы закрыть этот как дубликат).   -  person Zifre    schedule 31.07.2009
comment
@pete посмотрите комментарии точного дубликата. Спасибо   -  person    schedule 31.07.2009
comment
@Zifre Я думаю, что важнее получить ответы. второй вопрос предлагается исключить.   -  person    schedule 31.07.2009
comment
Обман stackoverflow.com/questions/408670/ stack-static-and-heap-in-c среди многих других. Вам также следует взглянуть на многих других.   -  person    schedule 31.07.2009
comment
@ Нил Баттерворт. КАК ЭТО ДУПЕР. пожалуйста, объясни   -  person    schedule 31.07.2009
comment
Если это обман, то я думаю, что этот вопрос намного ближе к заданному здесь: stackoverflow.com/questions/79923/   -  person Martin Liversage    schedule 31.07.2009
comment
@Martin Достаточно честно, это все еще обман.   -  person    schedule 31.07.2009
comment
Я удалил свой ответ и переместил его в stackoverflow.com/questions/79923/. @ultraman: Надеюсь, вы найдете достаточно информации, чтобы адекватно ответить на свой вопрос.   -  person Martin Liversage    schedule 31.07.2009
comment
@ultraman Ваш вопрос показывает, что вы не понимаете основ управления памятью, которое осуществляется ОС и не зависит от компилятора и языка. Для иллюстрации - функции хранятся в сегменте кода, а не в стеке или куче (как вы думаете). Поэтому, прежде чем думать о реализации менеджеров памяти, вам нужно понять некоторые основные принципы - поэтому люди продолжают давать вам все эти ссылки. Я предлагаю прочитать их.   -  person qrdl    schedule 31.07.2009


Ответы (1)


Думаю, на ваш вопрос можно легко написать хоть несколько глав для книги по Операционным системам. Предлагаю вам прочитать Таненбаум: Современные операционные системы.

Основное различие кучи и стека в том, что один для каждого элемента процесса, другой для элемента потока. Первоначально, когда программа запускается, она получает некоторую минимальную кучу и некоторый сегмент стека. Куча увеличена, стек статичен (для каждого потока). Если вы напишете рекурсивную функцию, которая не завершается (бесконечная рекурсия), вы получите переполнение стека;) Любой вызов функции имеет фрейм стека в сегменте стека, когда функция уходит, стек разматывается, и фрейм может использоваться следующая функция. Стек представляет собой непрерывную линейную структуру. В Linux вы можете настроить размер сегмента стека для процесса с помощью переменной среды. В Windows (по крайней мере, с MS Visual C ++) вы можете передать флаг компоновщика с размером сегмента стека. Переполнение стека также может происходить при выделении во время компиляции некоторого большого массива:

char test[1000000];

Куча - это отдельная история. Когда процесс запускается, размер кучи является некоторым значением по умолчанию и может варьироваться от ОС к ОС или конфигурации, используемой в этой ОС (например, в Windows это 2 МБ по умолчанию, насколько я помню). Кроме того, если вам нужно больше кучи, чтобы выделить больше места для переменных и т. Д., Она будет расти. Если программа не освобождает память кучи, она исчерпывается (или пространство кучи). Существуют разные структуры данных для реализации кучи, некоторые из них являются производными двоичного дерева, некоторые нет, например. Куча Фибоначчи (лес из деревьев). Вы можете прочитать статьи и т. Д. О том, как написать распределитель памяти. Эти структуры данных должны быть оптимизированы для поиска узла кучи, когда выделенный фрагмент необходимо отменить, или добавления (нахождения свободного фрагмента), когда требуется новое пространство кучи.

Каждый процесс в 32-битной ОС имеет 4 ГБ виртуального адресного пространства. Как вы понимаете, оперативной памяти не может быть столько, чтобы поместились все процессы с их 4 ГБ виртуального адресного пространства. Память ОС организована в виде страниц, которые заменяются на HD, когда они больше не нужны или срок их действия истек. Здесь на помощь приходит пейджинг. На страницы отображается все: процесс со стеком или растущая куча. Благодаря динамической структуре кучи, ее можно разместить на нескольких страницах. Вот почему доступ к куче может быть очень дорогостоящим, потому что, если страница не находится в памяти, происходит сбой страницы, и ОС должна загружать страницу с диска (а это может быть намного медленнее). Кадр стека выполняемого потока находится в кеш-памяти процессора, который намного быстрее ОЗУ.

Возможны разные типы кучи, могут быть кучи, которые очень быстро работают для небольших объектов, или кучи, которые очень эффективны в многопоточных средах. Александреску описывает в «Современном дизайне C ++», как разработать распределитель небольших объектов и кучу, которая управляет небольшими объектами. Эта реализация доступна в его библиотеке Loki C ++. Некоторые встроенные системы предлагают физически разные области памяти, где могут быть реализованы различные типы кучи. Написать собственный распределитель (диспетчер кучи и т. Д.) - тяжелая работа, если вы хотите превзойти компилятор.

С уважением,
Ованес

person ovanes    schedule 31.07.2009
comment
Было бы неплохо, если бы его можно было переместить в другой, практически идентичный вопрос ультрачеловека, stackoverflow.com/questions/1212797/ ... - person SamB; 25.05.2010