Какие области памяти есть в Java кроме стека и кучи
Что проверяют
Знаете ли вы устройство памяти JVM глубже двух слов и понимаете ли, что Android-приложение работает не на HotSpot, а на ART. Следом часто спрашивают, где в Android лежат пиксели Bitmap и почему растёт нативная память.
Как отвечать
Начните со спецификации JVM, она перечисляет области времени выполнения:
- регистр PC: у каждого потока свой, указывает на текущую инструкцию;
- стеки JVM и нативные стеки: по одному на поток, во фреймах локальные переменные и операнды, для JNI отдельный нативный стек;
- куча: объекты и массивы, общие для всех потоков;
- область методов: метаданные классов, байткод, статические поля. В HotSpot с Java 8 это Metaspace в нативной памяти вместо PermGen;
- пул констант времени выполнения: у каждого класса свой, ссылки на методы, поля и литералы.
Добавьте то, чего нет в спецификации, но что есть в процессе: кэш скомпилированного JIT-кода и память вне кучи через ByteBuffer.allocateDirect().
Дальше переходите к Android. ART работает с DEX-файлами, и куча у него устроена по-своему. В дампе кучи Android Studio видны три части: image (системный образ с классами, предзагруженными при старте), zygote (объекты, созданные Zygote до форка вашего процесса) и app (ваши объекты). Memory Profiler делит память процесса на Java, Native, Graphics, Stack, Code и Others. Пиксели Bitmap с Android 8.0 лежат в нативной куче: OutOfMemoryError в Java-куче из-за картинок случается реже, но общая память процесса растёт, и система может убить приложение.
Строковый пул отдельной областью не считается: с Java 7 он хранится в куче.
Где спотыкаются
Называют Eden, Survivor и Old Generation «областями кроме кучи». Это поколения внутри самой кучи, и то только у поколенческих сборщиков.
Переносят на Android настройки HotSpot: -Xmx, PermGen, Metaspace. Лимит кучи приложению задаёт система, а android:largeHeap лишь просит больше и ничего не гарантирует.
Смотрят только на Java-кучу и не замечают утечку в нативной памяти или графических буферах, из-за которой процесс и убивают.