Расскажите, из каких областей состоит память JVM и что в них хранится.
Короткий ответ
- Heap — объекты и массивы, общая для всех потоков
- Stack — у каждого потока свой, кадры вызовов и локальные переменные
- Metaspace — метаданные классов, с Java 8 вместо PermGen
- Ссылки лежат в стеке, сами объекты — в куче
- Heap делится на young и old generation для GC
- Переполнение кучи — OutOfMemoryError, стека — StackOverflowError
JVM делит память на кучу для объектов, стеки потоков для вызовов и Metaspace для метаданных классов.
Как сказать вслух
пример ответаОсновные области — это куча, стек и Metaspace. В куче живут все объекты, она общая для потоков и именно её чистит сборщик мусора. У каждого потока есть свой стек с кадрами вызовов методов и локальными переменными. А Metaspace хранит информацию о загруженных классах — раньше это называлось PermGen.
Подробный ответ
Основной ответ
Память JVM логически делится на несколько областей. Heap (куча) — общая область для всех потоков, где создаются объекты и массивы; именно её обслуживает сборщик мусора. Для поколенческих коллекторов куча делится на young generation (eden и survivor-области) и old generation. Каждый поток имеет собственный stack: при вызове метода туда кладётся кадр с локальными переменными, параметрами и адресом возврата; примитивы и ссылки лежат в стеке, а сами объекты — в куче. Metaspace (нативная память, с Java 8 вместо PermGen) хранит метаданные классов. Ещё есть область для JIT-скомпилированного кода (code cache) и нативные стеки.
Ключевые моменты
- Heap. Общая для потоков область объектов, управляется GC. Размер задаётся флагами -Xms/-Xmx.
- Stack. Свой у каждого потока; хранит кадры вызовов. Глубокая рекурсия даёт StackOverflowError.
- Metaspace. Метаданные классов в нативной памяти; растёт при утечках классов (classloader leak).
- Поколения кучи. Young (eden + survivor) для новых объектов, old — для долгоживущих; это основа поколенческого GC.
Практический контекст
На практике это нужно при разборе OutOfMemoryError и настройке контейнеров: лимиты -Xmx должны согласовываться с памятью пода, иначе OOM-killer. Интервьюер проверяет, понимаете ли вы разницу «ссылка в стеке — объект в куче» и знаете ли, что PermGen давно заменён Metaspace. Хороший плюс — упомянуть, что хип-дамп и jcmd/jmap помогают смотреть реальное распределение памяти.
Частые ошибки
- Говорят, что примитивы «всегда в стеке», забывая про поля объектов, которые лежат в куче
- Называют PermGen как актуальную область, хотя с Java 8 его нет
- Путают OutOfMemoryError и StackOverflowError и причины их возникновения