【发布时间】:2014-12-29 13:15:14
【问题描述】:
我想尽快调用OutOfMemoryError: PermGen space 错误。
我已经创建了自定义类加载器:
public class MyClassLoader extends URLClassLoader {
private MyClassLoader(URL[] urls) {
super(urls);
}
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
if (name.equals("com.memory.leaks.Leak")) {
return findClass(name);
}
return super.loadClass(name);
}
static IStructure newInstance() {
try {
final URL classSource = Structure.class.getProtectionDomain().getCodeSource().getLocation();
try (URLClassLoader cl = new MyClassLoader(new URL[] { classSource })) {
return (ILeak) cl.loadClass("com.memory.leaks.Leak").newInstance();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
这是一个由这个类加载器加载的Leak 类:
package com.memory.leaks;
public class Leak {
}
此代码将导致 OOME。
然后我修改了Leak 类,添加了 20 个名称很长的方法:
public void aaaaaaaaaaaaaaaa ...~ 50 chars... aaaaaaaa () {
}
由于方法名称驻留在 PermGen 中,这样的修改应该会加快 PermGen 的填充速度。然而,动态分析(使用 JVisualVM 和 VisualGC)表明它以几乎相同的速度完成:
修改前(71s):
修改后(69s):
我的问题很简单:为什么?
【问题讨论】:
-
那是哪个 Java 版本? FWIW,Orcle 的 JRE(8 岁以上)不再有 permgen
-
它是 Oracle JRE 1.7。我知道 PermGen 在 JRE 1.8 中被 Metaspace 取代。
标签: java memory-leaks permgen