У меня есть этот код для динамического создания класса и загрузки его
import javassist.CannotCompileException;
import javassist.ClassPool;
public class PermGenLeak {
private static final String PACKAGE_NAME = "com.jigarjoshi.permgenleak.";
public static void main(String[] args) throws CannotCompileException, InterruptedException {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
ClassPool pool = ClassPool.getDefault();
pool.makeClass(PACKAGE_NAME + i).toClass();
Thread.sleep(3);
}
}
}
Я запустил этот класс против Java 7 (jdk1.7.0_60) и, как и ожидалось, он заполнил PermGenSpace, а куча осталась неиспользованной изображение показывает сверхурочное использование сверхурочного времени и в конце JVM завершено
Теперь тот же код работал против Java 8 (jdk1.8.0_40-ea), и, как и ожидалось, он продолжал расширять собственную память (Metaspace), но удивительно, что для 1g Metaspace он потреблял 3g кучи в OldGen (почти 3x из Metaspace поддерживались времени)
изображение показывает сверхурочное время использования метапроцесса и пример использования системной памяти
это письмо от Jon Masamitsu и этот билет JEP говорит
интернированный
String
и статистика классов, а некоторые разные данные были перенесены в кучу
что именно делает это увеличение кучи при загрузке большего количества классов в Metaspace?