Ответ
Non-Heap память (внекучная память) в JVM — это область памяти, не управляемая стандартным сборщиком мусора (Garbage Collector). Она используется для служебных данных самой виртуальной машины.
Основные компоненты Non-Heap памяти:
- Metaspace (с Java 8): Хранит метаданные загруженных классов (структуры классов, методы, поля, байт-код). Заменил собой PermGen (Permanent Generation). Размер динамически меняется, ограничен параметром
MaxMetaspaceSize. - Code Cache: Область для хранения скомпилированного машинного кода JIT-компилятором (Just-In-Time).
- Память потоков (Thread Stacks): Выделяется под стек каждого потока.
- Память вне кучи, управляемая приложением:
- Direct ByteBuffers: Память, выделяемая вызовом
ByteBuffer.allocateDirect(), обходящая Java Heap и работающая напрямую с нативной памятью ОС. - Нативные библиотеки: Память, выделяемая через JNI (Java Native Interface).
- Direct ByteBuffers: Память, выделяемая вызовом
Пример утечки в Metaspace (ClassLoader leak):
// Динамическая генерация и загрузка классов
while (true) {
ClassLoader cl = new CustomClassLoader();
Class<?> c = cl.loadClass("com.example.GeneratedClass");
// Если классы/ClassLoader'ы не выгружаются, Metaspace заполняется
}
Ключевые параметры JVM для настройки:
-XX:MetaspaceSize— начальный размер Metaspace.-XX:MaxMetaspaceSize— максимальный размер Metaspace.-XX:ReservedCodeCacheSize— максимальный размер Code Cache.-XX:MaxDirectMemorySize— лимит для Direct ByteBuffers.
Мониторинг:
- Через JMX (
MemoryMXBean,MemoryPoolMXBean). - Утилитой
jcmd:jcmd <pid> VM.native_memory. - В профилировщиках (VisualVM, JMC, async-profiler).