
Утечка, которую не видит heap dump
Интересная ловушка: вызываешь string.intern() на динамических строках, приложение падает с OOM, делаешь heap dump — а там всё чисто. Где утечка?
🟢 Суть проблемы
String Pool до Java 7 жил в PermGen, с Java 7 переехал в heap. Казалось бы, проблема решена. Но нет.
Внутри String Pool использует нативную хеш-таблицу StringTable, которая живёт в native memory (вне heap). Когда ты делаешь intern(), в heap создаётся сама строка, но ссылка на неё хранится в нативной StringTable.
🟢 Что происходит
Строки попадают в heap (GC их уберёт), но StringTable в native memory растёт бесконечно. Размер StringTable фиксирован и задаётся -XX:StringTableSize. При переполнении — коллизии, деградация, OOM.
🟢 Как увидеть?
bashjcmd <pid> VM.stringtable
Или Native Memory Tracking:
bash-XX:NativeMemoryTracking=detail
jcmd <pid> VM.native_memory
Ищи раздел Symbol — там StringTable.
⚠️ String Pool — это не только heap. StringTable живёт в native memory, и это классическая офф-хип утечка.
Java Guru Если у вас установлено приложение,
вы можете сразу перейти в канал