Ответ
Хранение ссылочных типов (объектов) в JVM разделено на две части:
- Ссылка (переменная): Хранится либо в стеке потока (для локальных переменных), либо внутри другого объекта в куче (для полей класса). Она содержит адрес памяти объекта.
- Сам объект: Всегда создается в куче (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).
Почему такая схема? Куча общая для всех потоков, что позволяет объектам жить дольше метода, в котором они созданы. Стек — быстрая память, привязанная к жизненному циклу потока. Разделение упрощает управление памятью и сборку мусора.