为什么PermGen的填充速度不快?

时间:2014-12-29 13:15:15

标签: java memory-leaks permgen

我想尽快调用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):

Before modification

修改后(69s):

After modification

我的问题很简单:为什么?

1 个答案:

答案 0 :(得分:2)

为什么使用长名称的方法会显着增加类使用的空间量?类加载器将实现方法名称,注意该字符串已经存在于内存中并使用该字符串而不是新字符串。

如果你想增加一个类占用的空间量,那么声明很多静态字段。