Вкратце
Стек используется для распределения статической памяти, а куча - для распределения динамической памяти, оба хранятся в ОЗУ компьютера.
Подробнее
Стек
Стек представляет собой структуру данных «LIFO» (последний пришел - первым ушел), которой ЦП достаточно внимательно управляет и оптимизирует. Каждый раз, когда функция объявляет новую переменную, она «помещается» в стек. Затем каждый раз, когда функция завершается, все переменные, помещенные в стек этой функцией, освобождаются (то есть они удаляются). После освобождения переменной стека эта область памяти становится доступной для других переменных стека.
Преимущество использования стека для хранения переменных заключается в том, что память управляется за вас. Вам не нужно выделять память вручную или освобождать ее, если она вам больше не нужна. Более того, поскольку ЦП так эффективно организует стековую память, чтение и запись в переменные стека происходит очень быстро.
Больше можно найти здесь .
Куча
Куча - это область памяти вашего компьютера, которая не управляется автоматически и не так жестко управляется ЦП. Это более свободно плавающая область памяти (и больше). Чтобы выделить память в куче, вы должны использовать malloc () или calloc (), которые являются встроенными функциями C. После того, как вы выделили память в куче, вы должны использовать free () для освобождения этой памяти, когда она вам больше не понадобится.
Если вы этого не сделаете, в вашей программе произойдет так называемая утечка памяти. То есть память в куче по-прежнему будет выделена (и не будет доступна другим процессам). Как мы увидим в разделе отладки, существует инструмент под названием Valgrind, который может помочь вам обнаружить утечки памяти.
В отличие от стека, куча не имеет ограничений размера на переменный размер (кроме очевидных физических ограничений вашего компьютера). Память кучи немного медленнее для чтения и записи, потому что для доступа к памяти в куче необходимо использовать указатели. Мы скоро поговорим об указателях.
В отличие от стека, переменные, созданные в куче, доступны для любой функции в любом месте вашей программы. Переменные кучи по сути глобальны по своему охвату.
Больше можно найти здесь .
Переменные, выделенные в стеке, хранятся непосредственно в памяти, и доступ к этой памяти очень быстрый, а ее выделение обрабатывается при компиляции программы. Когда функция или метод вызывает другую функцию, которая по очереди вызывает другую функцию и т. Д., Выполнение всех этих функций приостанавливается до тех пор, пока самая последняя функция не вернет свое значение. Стек всегда резервируется в порядке LIFO, последний зарезервированный блок всегда является следующим блоком, который должен быть освобожден. Это упрощает отслеживание стека, освобождение блока из стека - это не что иное, как настройка одного указателя.
Переменные, выделенные в куче, имеют свою память, выделенную во время выполнения, и доступ к этой памяти немного медленнее, но размер кучи ограничен только размером виртуальной памяти. Элементы кучи не зависят друг от друга и всегда могут быть доступны случайным образом в любое время. Вы можете выделить блок в любое время и освободить его в любое время. Это значительно усложняет отслеживание того, какие части кучи выделены или свободны в любой момент времени.
Вы можете использовать стек, если точно знаете, сколько данных вам нужно выделить до времени компиляции, и он не слишком велик. Вы можете использовать кучу, если не знаете точно, сколько данных вам понадобится во время выполнения или если вам нужно выделить много данных.
В многопоточной ситуации каждый поток будет иметь свой собственный полностью независимый стек, но они будут совместно использовать кучу. Стек зависит от потока, а куча зависит от приложения. Стек важно учитывать при обработке исключений и выполнении потоков.
Каждый поток получает стек, в то время как обычно существует только одна куча для приложения (хотя нередко бывает несколько куч для разных типов распределения).
Во время выполнения, если приложению требуется больше кучи, оно может выделить память из свободной памяти, а если стеку требуется память, он может выделить память из свободной памяти, выделенной для приложения.
Даже более подробная информация дана здесь и здесь <29>.
Теперь перейдите на ответы на ваши вопросы .
В какой степени они контролируются ОС или языковой средой выполнения?
ОС выделяет стек для каждого потока системного уровня при создании потока. Обычно ОС вызывается средой выполнения языка для выделения кучи для приложения.
Больше можно найти здесь .
Какова их сфера действия?
Уже занесено в топ.
«Вы можете использовать стек, если вы точно знаете, сколько данных вам нужно выделить до времени компиляции, и он не слишком большой. Вы можете использовать кучу, если не знаете точно, сколько данных вам понадобится в времени выполнения или если вам нужно выделить много данных. "
Больше можно найти в здесь.
От чего зависит размер каждого из них?
Размер стека устанавливается ОС при создании потока. Размер кучи устанавливается при запуске приложения, но он может увеличиваться по мере необходимости в пространстве (распределитель запрашивает у операционной системы больше памяти).
Что делает человека быстрее?
Распределение стека происходит намного быстрее, поскольку все, что он действительно делает, это перемещает указатель стека. Используя пулы памяти, вы можете получить сопоставимую производительность за счет распределения кучи, но это связано с небольшой дополнительной сложностью и собственными головными болями.
Кроме того, соотношение стека и кучи зависит не только от производительности; он также многое говорит об ожидаемом времени жизни объектов.
Подробности можно найти в здесь .
действительно хорошее объяснение можно найти здесь В чем разница между стеком и кучей?
Также (действительно) хорошо: codeproject.com/Articles/76153/… (часть стека / кучи)
youtube.com/watch?v=clOUdVDDzIM&spfreload=5
См. Также Stack Clash. Исправления Stack Clash затронули некоторые аспекты системных переменных и поведения, например
rlimit_stack
. Также см. Red Hat Issue 1463241@mattshane. Определения стека и кучи вообще не зависят от типов значений и ссылок. Другими словами, стек и куча могут быть полностью определены, даже если типы значений и ссылочные типы никогда не существовали. Кроме того, для понимания типов значений и ссылок стек - это просто деталь реализации. Эрик Липперт: Стек - это деталь реализации, часть первая.
Непонятно в ответах: для языковой среды выполнения (например, .NET) существует один стек на поток для управления вызовами методов / локальными переменными и только одна куча, установленная для всех процессов среды выполнения. Куча контролируется сборщиком мусора. Стеки времени выполнения / пространство кучи - это часть непрерывной виртуальной памяти, выделяемой ОС для процессов (которая сама загружается физическими блоками ОЗУ в произвольном порядке) по запросу процессов. Путаница вокруг «стеков» возникает из-за наличия в компьютере множества видов «стеков», не связанных со стеками языковой среды выполнения. «Стек» - это просто структура хранения LIFO.
Если вы хотите увидеть симуляцию того, как выглядят стек и куча во время выполнения программы на C, попробуйте C Tutor.