Java8 metaspace & heap usage
2022-09-03 07:28:16
我有这个代码来动态生成类并加载它
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,堆仍然未使用的图像显示permgen使用加班,最后JVM被终止
现在,相同的代码运行在Java 8(jdk1.8.0_40-ea)上,并且正如预期的那样,它不断扩展本机内存(Metaspace),但令人惊讶的是,对于1g的Metaspace,它在OldGen中消耗了3g的Heap(随着时间的推移,几乎保持了3倍的Metaspace)。
图像显示超时的元空间使用和系统内存使用示例
这封来自Jon Masamitsu的电子邮件和这张JEP票证说
实习生和班级统计数据以及一些杂项数据已移至堆
String
究竟是什么让堆在将更多类加载到元空间中而增加?