Подтвердить что ты не робот

Почему память разбивается на стек и кучу?

Возможный дубликат:
Что и где находятся стек и куча

У меня есть пара вопросов о стеке и куче.

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

Однако я всегда задавался вопросом, как работают стек и куча. ОЗУ - это всего лишь один кусок памяти, он не делится на "стек" и "кучу" (или это?). Если это так, , почему мы разделяем память в стеке и кучу в первую очередь?

OS может просто позволить нам иметь возможность выделить все в стеке → все идет быстрее → счастливый мир?

Я уверен, что это не так. Но почему!? Может ли кто-нибудь дать мне подробный ответ?

Извините, если этот пост является дубликатом какого-либо сообщения, когда-либо сделанного кем-то, там так много связано со стеком и кучей, я не мог найти точный вопрос, который у меня был. Если вам это известно, продолжайте и свяжите его.

4b9b3361

Ответ 1

Стек: Стек используется как своего рода временная скрепка для использования блоком кода, который в настоящее время выполняется, и любым блоком, называемым текущим, и любым блоком, который называется этим, и скоро. Когда текущий блок выходит, локальные переменные, которые он использует, забываются. Как видно из названия, стек используется в последнем, вначале.

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

Куча: Куча другая - нет конкретного порядка. Если вы хотите выделить память в блоке кода и иметь эту карту памяти за пределами конца блока, вы выделяете ее в кучу. Конечно, вам также нужно будет хранить указатель/ссылку на него где-нибудь, чтобы другой код мог найти эту память; большинство языков обеспечивают размещение, которое.

Скорость: Различия в скорости не связаны с каким-либо свойством самой памяти - как вы говорите в своем вопросе, как стек, так и куча обычно обитают в одной и той же физической памяти. Выделение пространства в стеке происходит быстро из-за стеков LIFO-природы: если вы нажимаете что-то в стек, там может быть только одно место. Напротив, выделение блока в куче требует нахождения достаточно большой смежной свободной области в памяти. Выделение стека может быть столь же быстрым, как и одна команда; для распределения кучи требуется вызов функции выделения памяти, например malloc().

Static v. dynamic: Выделение памяти в куче динамически - можно ли выделить блок и размер блока, можно определить в соответствии с вводом, который программа получает во время ее запуска. Регионы памяти, выделенные в куче, могут быть даже изменены при необходимости. Также возможно динамически выделять память в стеке (см. Стандартную библиотечную функцию C alloca()), но эта память будет потеряна, как только выйдет текущая функция. Распределения стека обычно статичны - компилятор определяет, сколько места требуется для (не регистровых) параметров, возвращаемых данных и локальных переменных, и генерирует код для резервирования необходимого пространства в стеке при вызове функции.

Пример: Представьте, что вы создаете текстовый процессор. Вы не можете заранее знать, насколько велика будет документ или даже сколько документов будет использоваться одновременно. В то же время вы хотите, чтобы пользовательские документы оставались в памяти, пока пользователь хочет их открыть. Если вы попытаетесь выделить память для документов в стеке, вам будет трудно иметь сразу несколько открытий, и вам нужно будет создать одну функцию, которая создает, редактирует, сохраняет и закрывает документ. Выделение пространства в куче позволяет создавать столько документов, сколько вам нужно, каждый размер соответственно для содержащихся в нем данных и не связывать время жизни документов со временем жизни какой-либо конкретной функции.

Резюме: В двух словах стек содержит значения переменных (иногда используются регистры), а куча используется для выделения памяти, которая будет использоваться за время жизни текущего блока.

Ответ 2

Вы можете использовать стек не только потому, что для стека требуется порядок выделения и освобождения от первого порядка (т.е. вы можете освобождать только самые последние выделенные данные; в стеке вы не можете освободить некоторые старые данные и сохранить некоторые новые).

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

И куча не имеет четко определенного значения (кроме "динамически выделенной памяти, которая не находится в стеке" ). На самом деле, в системах Linux выделение большого объема памяти с помощью системного вызова mmap довольно быстро (но malloc реализация пытается избежать mmap и предпочитайте повторно использовать free -d память). Проблема заключается в распределении небольших зон памяти.

И подробнее о методах сбора мусора. В C или С++ вы можете использовать Boehm GC

Стек часто полезен, особенно для рекурсивных вызовов функций. Он настолько полезен (например, в C), что на сегодняшний день процессоры обычно имеют специальный регистр указателя стека (используемый машинами для CALL и RET для вызова и возврата). Но это не всегда так; на некоторых процессорах (например, IBM360) указатель стека является обычным регистром, а не жестко закодированным.

Ответ 3

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

Stack - очень примитивная абстракция, которая необходима любому микропроцессору для выполнения инструкций на пару операндов (обычно регистров процессора или адресов памяти).

Куча - это общая область памяти распределения, в которой обычно вы хотите хранить данные, которые не привязаны к стеку, то есть их продолжительность жизни больше, чем если бы они были сохранены в стеке или, как сказано другим способом, данные будут обращается к различным частям кода.