我想尽快调用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。
然后我通过添加20个具有很长名称的方法来修改Leak
类:
public void aaaaaaaaaaaaaaaa ...~ 50 chars... aaaaaaaa () {
}
由于方法名称位于PermGen中,因此这种修改应加快填充PermGen。但是,动态分析(使用JVisualVM和VisualGC)表明它的速度几乎相同:
修改前(71s):
修改后(69s):
我的问题很简单:为什么?
答案 0 :(得分:2)
为什么使用长名称的方法会显着增加类使用的空间量?类加载器将实现方法名称,注意该字符串已经存在于内存中并使用该字符串而不是新字符串。
如果你想增加一个类占用的空间量,那么声明很多静态字段。