我有一个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进行分析。查看您加载的类。检查是否有意外情况,尤其是重复类。它还有一个类加载器资源管理器。
编辑:从理论上讲,你也可能是在不断地生成代理。