Что такое куча и стек?
В Java (и в большинстве языков с автоматическим управлением памятью) куча (heap) и стек (stack) — это две разные области памяти, каждая со своей задачей, скоростью доступа и управлением.
📦 Куча (Heap)
Что это:
-
Область памяти, выделяемая под объекты и их поля.
-
Используется для хранения данных, которые создаются во время выполнения программы и могут жить долго.
-
Управляется сборщиком мусора (Garbage Collector).
Пример:
String name = new String("Alice");
User user = new User();
→ Объекты String и User создаются в куче, а ссылки на них могут храниться в стеке.
Характеристики:
-
Медленнее, чем стек (требуется больше времени на выделение/освобождение).
-
Общие для всех потоков (могут использоваться многопоточно).
-
Объекты в куче живут до тех пор, пока на них существуют ссылки — после этого их удаляет GC.
Стек (Stack)
Что это:
-
Область памяти, выделяемая для выполнения методов, хранения локальных переменных, аргументов методов и т.д.
-
Организован по принципу LIFO (последним пришёл — первым вышел).
Пример:
void greet() {
int age = 30;
String hello = "Hi";
}
→ Переменные age и hello (сама ссылка) находятся в стеке. Строка "Hi" — в куче.
Характеристики:
-
Очень быстрый доступ (память выделяется и освобождается автоматически при вызове/выходе из метода).
-
Отдельный стек для каждого потока.
-
Жизненный цикл переменных ограничен временем выполнения метода.
🔍 Главное отличие — что где хранится
Элемент | Где хранится |
---|---|
Примитив внутри метода | В стеке |
--- | --- |
Ссылка на объект | В стеке |
--- | --- |
Сам объект | В куче |
--- | --- |
Локальные переменные | В стеке |
--- | --- |
Поля объекта | В куче (в составе объекта) |
--- | --- |
Объекты классов | В куче |
--- | --- |
🔄 Взаимодействие кучи и стека
void example() {
User user = new User(); // ссылка в стеке, объект в куче
}
-
Когда метод example() вызывается — в стеке создаются переменные.
-
При создании new User() — объект хранится в куче.
-
Когда метод завершает выполнение — стек очищается.
-
Если ни одна другая часть программы не ссылается на user — GC удалит объект из кучи.
⚠️ Важно
-
Стек работает быстро, но объём его ограничен (обычно 512 КБ – 1 МБ на поток).
-
Куча больше, но работает медленнее и требует GC.
-
Стековые переменные исчезают при выходе из метода.
-
Объекты в куче могут жить дольше одного вызова, и делятся между методами и потоками.
📌 Резюме
Параметр | Стек | Куча |
---|---|---|
Что хранит | Локальные переменные, ссылки | Объекты и их поля |
--- | --- | --- |
Область действия | Ограничена методом | Живёт, пока на объект есть ссылка |
--- | --- | --- |
Скорость доступа | Очень высокая | Ниже, чем у стека |
--- | --- | --- |
Управление памятью | Автоматически (вызов/выход из метода) | Сборщик мусора (GC) |
--- | --- | --- |
Доступность | Только текущий поток | Общая для всех потоков |
--- | --- | --- |
Понимание этих областей памяти важно для эффективного написания производительного и безопасного Java-кода.