Ответ
Metaspace — это область нативной (внекучевой) памяти, используемая JVM начиная с Java 8 для хранения метаданных загруженных классов. Она заменила собой PermGen (Permanent Generation), которая располагалась в куче.
Что хранится в Metaspace?
- Структуры классов (Class metadata): имена, методы, поля, сигнатуры.
- Байт-код методов.
- Константы пула строк (String Table), относящиеся к классам.
- Аннотации.
- Оптимизированный код, сгенерированный JIT-компилятором.
| Ключевые отличия от PermGen: | Характеристика | PermGen (до Java 7) | Metaspace (Java 8+) |
|---|---|---|---|
| Расположение | Часть кучи Java (Heap) | Нативная память ОС (вне кучи) | |
| Размер | Фиксированный, задаётся -XX:MaxPermSize |
Динамический, ограничен доступной нативной памятью | |
| Очистка | Полная сборка мусора (Full GC) | Сборка мусора, вызванная нехваткой памяти в Metaspace | |
| Причина OutOfMemoryError | OutOfMemoryError: PermGen space |
OutOfMemoryError: Metaspace |
Управление размером Metaspace (флаги JVM):
# Начальный размер Metaspace (по умолчанию зависит от платформы)
-XX:MetaspaceSize=64m
# Максимальный размер Metaspace (по умолчанию не ограничен, используется вся нативная память)
-XX:MaxMetaspaceSize=256m
# Частота сборки мусора класса (Class Unloading)
-XX:MinMetaspaceFreeRatio=40
-XX:MaxMetaspaceFreeRatio=70
Типичная проблема: утечка памяти в Metaspace. Возникает, когда загрузчики классов (ClassLoader) не выгружаются, и метаданные накапливаются. Частая причина в серверах приложений (Tomcat, JBoss) при частом redeploy приложений.
Почему это важно? Metaspace устранила главную проблему PermGen — необходимость заранее угадывать размер для хранения метаданных, что снижало риск OutOfMemoryError. Однако теперь утечки могут потреблять всю нативную память системы, поэтому мониторинг и настройка лимитов остаются критически важными.