【问题标题】:Why PermGen is not populated faster?为什么 PermGen 没有更快地填充?
【发布时间】: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


【解决方案1】:

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

如果您想增加类占用的空间量,请声明大量静态字段。

【讨论】:

  • 我完全忘记了静态字段也存在于 PermGen 中。谢谢!
猜你喜欢
  • 2020-04-28
  • 2017-01-18
  • 1970-01-01
  • 1970-01-01
  • 2015-04-28
  • 2011-12-28
  • 2017-01-21
  • 2014-10-03
  • 2010-12-29
相关资源
最近更新 更多