Ответ
Помимо кучи (Heap) и стека (Stack), JVM управляет несколькими другими критически важными областями памяти:
1. Metaspace (заменяет Permanent Generation / PermGen)
- Назначение: Хранит метаданные классов: структуры класса (имя, методы, поля), байт-код, константы времени выполнения, аннотации. До Java 7 сюда же помещались строковые литералы из пула строк (String Intern Pool).
- Особенность: Располагается вне кучи (off-heap) в нативной памяти ОС. Её размер автоматически регулируется, что предотвращает ошибку
OutOfMemoryError: PermGen space.// Загрузка класса заставляет JVM хранить его метаданные в Metaspace. Class<?> clazz = MyCustomClass.class;
2. Code Cache
- Назначение: Хранит скомпилированный машинный код, сгенерированный JIT-компилятором (Just-In-Time) из часто выполняемых участков байт-кода ("горячих" методов). Это оптимизация для скорости выполнения.
3. Memory Mapped Files & Direct Buffers
- Назначение: Область вне кучи, используемая для работы с
java.nio(New I/O). Позволяет эффективно читать/писать файлы, отображая их прямо в память, минуя кучу и снижая нагрузку на сборщик мусора (GC).// Пример использования Direct ByteBuffer (располагается вне кучи) ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024);
4. Thread-Local Allocation Buffer (TLAB)
- Назначение: Небольшой, выделенный для каждого потока регион внутри Eden Space кучи. Поток может быстро выделять в нём память под новые объекты без синхронизации с другими потоками, что ускоряет аллокацию.
Эти области вместе обеспечивают эффективное выполнение, компиляцию и управление метаданными приложения.