【发布时间】:2014-10-19 21:12:47
【问题描述】:
我有这段代码可以动态生成类并加载它
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 的堆(几乎 3 倍的 Metaspace 维持在时间)
图片显示超空间使用超时和系统内存使用示例
this email from Jon Masamitsu 和this JEP ticket 说
interned
String和 Class stats 和一些杂项数据已移至 Heap
在将更多类加载到 Metaspace 时,究竟是什么导致了堆的增加?
【问题讨论】:
标签: java jvm java-8 jvm-hotspot metaspace