如何诊断Java 8元空间泄漏



我有一个J2EE应用程序,它有一些有趣的行为。。。堆的行为似乎很好,随着时间的推移,随着垃圾收集的增加和减少,这是意料之中的事。没有明显的长期堆扩展。然而,元空间只是以每小时20 Mb左右的速度稳定增长,直到我们到达MaxMetaspace并遇到OOME。我已经尝试了并行和G1垃圾收集器(jdk1.8.0_40)

该应用程序在执行过程中没有被重新部署,因此看起来不像是典型的类加载器泄漏。有人对如何追查这次泄漏的源头有什么建议吗?

java.lang.OutOfMemoryError:Metaspace的主要原因是:

  • 类过多
  • 太大的类正在加载到元空间

如果您想重新创建问题,请使用以下代码片段:

public class Metaspace {
static javassist.ClassPool cp = javassist.ClassPool.getDefault();
public static void main(String[] args) throws Exception {
    for (int i = 0; ; i++) { 
        Class c = cp.makeClass("eu.plumbr.demo.Generated" + i).toClass();
    }
  }
}

所有这些生成的类定义最终都会消耗元空间。

Maven repo中的Javaassist。

你可以在这里找到更多关于OOME的信息

做一个堆转储并使用Eclipse MAT进行分析。查看您加载的类。检查是否有意外情况,尤其是重复类。它还有一个类加载器资源管理器。

编辑:从理论上讲,你也可能是在不断地生成代理。

最新更新