38

我有一个具有一些有趣行为的 J2EE 应用程序......堆似乎表现良好,随着时间的推移随着垃圾收集而增长和缩小。没有明显的整体长期堆扩展。然而,元空间以每小时 20 Mb 的速度稳定增长,直到我们到达 MaxMetaspace 并遇到 OOME。我已经尝试过并行和 G1 垃圾收集器(jdk1.8.0_40)。

应用程序在执行期间没有被重新部署,所以它看起来不像是典型的类加载器泄漏。有没有人有关于如何追踪这个泄漏源的建议?

4

2 回答 2

7

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

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

于 2015-08-18T08:42:49.197 回答
7

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 的更多信息

于 2015-08-12T13:05:10.507 回答