Что хранится в стеке (Stack) памяти JVM?

Ответ

Стек (Stack) в JVM — это область памяти, выделенная для каждого потока выполнения. В нём хранятся фреймы методов (stack frames), которые создаются при вызове метода и уничтожаются при его завершении (возврате).

Что хранится во фрейме метода:

  1. Локальные переменные метода:
    • Примитивные типы (int, boolean, char и т.д.) — хранятся непосредственно в стеке.
    • Ссылки (reference) на объекты — хранятся в стеке, а сами объекты находятся в куче (Heap).
  2. Операндный стек (Operand Stack) – Рабочая область для вычислений (временные результаты операций).
  3. Ссылка на текущий объект (this) – Для нестатических методов.
  4. Ссылка на константный пул (run-time constant pool) класса для разрешения символов.
  5. Информация для возврата управления – Адрес возврата после завершения метода.

Пример работы стека:

public class StackExample {
    public static void main(String[] args) { // Фрейм main
        int x = 10; // Примитив 'x' — в стеке (фрейм main)
        Object obj = new Object(); // Ссылка 'obj' — в стеке, объект Object — в куче
        int result = calculate(x); // Создаётся фрейм для calculate
    }

    static int calculate(int a) { // Фрейм calculate
        int b = a * 2; // Примитивы 'a' и 'b' — в стеке (фрейм calculate)
        return b;
    } // Фрейм calculate уничтожается, значение 'b' передаётся в фрейм main
}

Ключевые особенности:

  • Потоко-локальная память: У каждого потока свой стек.
  • Быстрый доступ: Выделение и очистка памяти происходят по простому принципу LIFO.
  • Ограниченный размер: Обычно меньше, чем у кучи. Переполнение приводит к StackOverflowError (часто из-за бесконечной рекурсии).
  • Не требует сборки мусора — фреймы удаляются сразу при выходе из метода.

Ответ 18+ 🔞

Да ты посмотри, какая штука интересная, блядь! Стек в JVM — это типа его личная тетрадка для каждого потока, куда он записывает, что и как делает. Представь, каждый поток — это отдельный работяга, и у каждого своя стопка бумажек на столе, сука.

На каждой такой бумажке — фрейм метода — записано, чем он сейчас занят. Вызвал метод — положил новую бумажку сверху. Закончил — выкинул её в урну. Всё просто, как три копейки!

А что же он там, на этой бумажке, калякает?

  1. Свои локальные штуки: Циферки типа int или boolean пишет прямо тут. А вот если создал какой-нибудь объект — new Object() — то сам объект валяется в общей куче, как на свалке, а на бумажке он лишь адресок этой свалки пишет, ссылку, блядь.
  2. Черновик для вычислений (Операндный стек): Тут он промежуточные результаты плюсует-минусует, перед тем как записать куда надо.
  3. Пометка «это я» (this): Если метод не статический, то чтобы не забыть, с каким объектом работает.
  4. Ссылка на шпаргалку (константный пул): Чтобы знать, где искать константы и названия методов.
  5. Куда возвращаться: Адрес, куда ткнуть носом, когда работу закончит.

Смотри, как это в жизни выглядит, ёпта:

public class StackExample {
    public static void main(String[] args) { // Положил фрейм main
        int x = 10; // Циферку 10 в стопку записал
        Object obj = new Object(); // Адресок объекта на бумажке, сам объект — в куче, в общем бардаке
        int result = calculate(x); // Опа, новый вызов! Кладёт сверху фрейм для calculate!
    }

    static int calculate(int a) { // Работает уже на новой бумажке
        int b = a * 2; // Колдует с цифрами a и b прямо тут, в своём фрейме
        return b;
    } // Всё, отработал! Выкидывает свою бумажку, результат 'b' швыряет вниз, во фрейм main
}

А теперь главные фишки, чтобы не облажаться:

  • Свой у каждого потока: Один поток в свой стек плюёт, другой — в свой. Не пересекаются, не дерутся.
  • Быстро, как чёрт: Выделил память — засунул фрейм сверху. Удалил — выкинул верхний. Всё по принципу «последний зашёл — первый вышел», LIFO, блядь.
  • Маленький, сука: Размер-то у него ограниченный, не как у кучи. Если слишком глубоко засунешься в рекурсию и будешь класть фрейм на фрейм — StackOverflowError тебе в сраку, и всё, приехали.
  • Сам убирает за собой: Сборщик мусора тут не пасётся. Закончил метод — фрейм нахуй, память свободна. Красота!