我有这段代码可以动态生成类并加载它
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 的堆(随着时间的推移,几乎是 Metaspace 的 3 倍)
图像显示 Metaspace 使用超时和系统内存使用示例
这封来自 Jon Masamitsu 的电子邮件和这张 JEP 票说
实习生
String
和班级统计数据以及一些杂项数据已移至堆
当将更多类加载到 Metaspace 时,究竟是什么导致了堆的增加?