← Назад к вопросам

В чём разница между Stack и Heap памятью в Java?

2.0 Middle🔥 131 комментариев
#Docker, Kubernetes и DevOps#JVM и управление памятью

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Разница между Stack и Heap памятью в Java

Stack и Heap — это два фундаментально различных способа управления памятью в Java, каждый из которых используется для разных целей и имеет свои характеристики.

Stack память

Stack — это потокобезопасная структура данных типа LIFO (Last In First Out), где память выделяется и освобождается в строго определённом порядке.

Характеристики:

  • Хранит примитивные значения (int, boolean, double и т.д.) и ссылки на объекты
  • Память выделяется и освобождается автоматически при входе/выходе из метода
  • Каждый поток имеет свой собственный Stack
  • Размер Stack фиксирован и ограничен (по умолчанию 1MB на Java)
  • Очень быстрый доступ к памяти
  • При переполнении выбрасывается StackOverflowError
public void example() {
    int age = 25;              // примитив — в Stack
    String name = "John";      // ссылка на объект — в Stack
    Person person = new Person(); // ссылка на объект — в Stack
}

Heap память

Heap — это память, которая используется для динамического выделения объектов во время выполнения программы.

Характеристики:

  • Хранит объекты (всё, что создано с помощью new)
  • Память выделяется динамически в момент создания объекта
  • Общая для всех потоков — может быть конкурентный доступ
  • Размер Heap намного больше Stack (обычно несколько GB)
  • Доступ медленнее, чем к Stack
  • Управляется Garbage Collector (GC)
  • При заполнении выбрасывается OutOfMemoryError
public void example() {
    Person person = new Person("John", 25);
    // person (ссылка) — в Stack
    // объект Person — в Heap
    // GC удалит объект, когда на него не будет ссылок
}

Визуальное сравнение

public class MemoryExample {
    public static void main(String[] args) {
        int x = 10;                      // Stack: примитив
        int[] arr = new int[]{1, 2, 3};  // Stack: ссылка arr, Heap: массив
        String str = "Hello";             // Stack: ссылка str, Heap: объект String
        Person p = new Person("Alice");  // Stack: ссылка p, Heap: объект Person
    }
}

Таблица сравнения

ПараметрStackHeap
Тип данныхПримитивы + ссылкиОбъекты
РазмерОграничен (1-2MB)Больше (ГБ)
СкоростьБыстроМедленнее
ДоступThread-safeТребует синхронизации
ОсвобождениеАвтоматическоеGarbage Collector
Ошибка переполненияStackOverflowErrorOutOfMemoryError

Жизненный цикл объектов

public void lifecycleExample() {
    // 1. Объект создан в Heap, ссылка в Stack
    String message = new String("Hello");
    
    // 2. Используем объект
    System.out.println(message);
    
    // 3. Выходим из метода
    // Ссылка удаляется из Stack
    // Объект в Heap помечается для удаления (если нет других ссылок)
    // GC удалит объект из Heap в непредсказуемый момент
}

Практические последствия

Stack переполнение происходит при глубокой рекурсии:

public long factorial(int n) {
    if (n == 0) return 1;
    return n * factorial(n - 1);  // каждый вызов добавляет frame в Stack
}

factorial(50000);  // StackOverflowError!

Heap переполнение происходит при массовом создании объектов:

List<Integer> list = new ArrayList<>();
while (true) {
    list.add(new Integer(1));  // объекты накапливаются в Heap
}  // OutOfMemoryError!

Почему это важно знать?

  • Производительность: Stack быстрее, поэтому используй примитивы где можно
  • Многопоточность: каждый поток имеет свой Stack — избегай проблем с синхронизацией примитивов
  • Утечки памяти: неудаляемые ссылки на объекты предотвращают их удаление GC
  • Оптимизация памяти: понимание разницы помогает писать более эффективный код

Это фундаментальное знание, необходимое для написания безопасного и производительного Java-кода.

В чём разница между Stack и Heap памятью в Java? | PrepBro