Найти тему

#4 Стек vs Куча

Оглавление

Кратко про основные различия (этого ответа достаточно на собеседовании):

🟰 Стек работает быстрее, потокобезопасен и имеет фиксированный размер. Управляется ОС. Хранит локальные переменные и аргументы функций.

💩 Память в куче динамически расширяемая и требует ручного управления или участия сборщика мусора. Может хранить глобальные переменные и ссылки (указатели).

🟰 Выделение памяти в стеке последовательно и фиксировано на этапе компиляции, и нельзя изменять размер стека после начала выполнения программы.

💩 Динамическое выделение в куче может привести к фрагментации памяти.

А теперь подробно.

Стек (Stack)

Аллокация памяти, другими словами, ее выделение происходит в стеке вызовов функций. Пространство памяти выделяется блоками. Компилятор знает размер памяти, который нужно выделить. Когда вызывается функция, память для её переменных выделяется в стеке и освобождается после завершения вызова функции.

Размер стека вызовов определяется многими факторами. Архитектура компьютера, на котором запущена программа, язык программирования и общий объем доступной системной памяти могут повлиять на размер программы. Если программа требует больше памяти, чем было выделено, это приведет к переполнению стека — stack overflow . В этой ситуации программа может зависнуть.

Стек работает в порядке LIFO (Last In, First Out), последний добавленный в стек кусок памяти будет первым в очереди на вывод из стека.

Куча (Heap)

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

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

Память кучи является глобальной. К ней можно получить доступ или изменить внутри программы по ссылке. В отличие от стека, она не ограничена функцией, в которой была выделена. Это делает выделение памяти в куче гибким, но не безопасным для потоков, так как любой, кто имеет ссылку, может читать и записывать данные.

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

Escape analysis

Одна из фаз компилятора Go, которая анализирует код и определяет какие переменные должны быть аллоцированы в стек, а какие помещены в кучу. Команда для escape analysis запущенная в корне репозитория:

-2

Наука
7 млн интересуются