Где хранятся ссылочные типы данных в памяти JVM?

«Где хранятся ссылочные типы данных в памяти JVM?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Хранение ссылочных типов (объектов) в JVM разделено на две части:

  1. Ссылка (переменная): Хранится либо в стеке потока (для локальных переменных), либо внутри другого объекта в куче (для полей класса). Она содержит адрес памяти объекта.
  2. Сам объект: Всегда создается в куче (Heap Memory).

Визуализация:

public class Example {
    private Object fieldRef = new Object(); // 1. fieldRef (ссылка) - в куче (часть объекта Example)
                                            // 2. new Object() (объект) - в куче
    public void method() {
        Object localRef = new String("test"); // 1. localRef (ссылка) - в стеке
                                              // 2. new String(...) (объект) - в куче
    }
}

Детализация кучи:

  • Young Generation (Eden, S0, S1): Здесь создаются новые объекты. Происходят частые сборки мусора (Minor GC).
  • Old Generation (Tenured): Сюда перемещаются объекты, пережившие несколько сборок в Young Generation.
  • Metaspace (ранее PermGen): Хранит метаданные классов (структуры Class).

Почему такая схема? Куча общая для всех потоков, что позволяет объектам жить дольше метода, в котором они созданы. Стек — быстрая память, привязанная к жизненному циклу потока. Разделение упрощает управление памятью и сборку мусора.