memory-leaks - 如何分析 Java 8 压缩类空间中的内存泄漏?

标签 memory-leaks jaxb java-8 out-of-memory metadata

一些上下文:我们已将 Web 应用程序的环境从在 Java 7 上运行升级到在 Java 8 和 Tomcat 8 上运行(64 位架构,堆大小约 2 GB,永久代大小 = 256 MB,对元空间大小没有限制)。过了一会儿,我们开始收到以下错误:

java.lang.OutOfMemoryError:压缩的类空间

这意味着 UseCompressedClassPointers 所需的空间超过了 CompressedClassSpaceSize。那时,VisualVM 显示了 2 GB 的元空间大小。

现在使用 VisualVM 工具,我们可以看到元空间大小随着每个请求大约 3 MB 不断增加,但是堆似乎没有这样做。堆使用量呈锯齿形,每次 GC 后都会回到相同的低点。

我只能在使用 Java JAXB 操作时才知道应用程序正在泄漏元数据,但我无法用 VisualVM 证明这一点。

应用程序依赖 webservices-rt-1.4 作为 JAXB 实现提供者。应用程序使用编码、解码。 XSD 的类生成是使用 maven-jaxb2-plugin-0.13.1 完成的。

更新:

在跟踪类加载和卸载后,我发现 WebAppClassLoader 多次将相同的 JAXB 类加载到内存中,但从未清理过。此外,堆中没有它们的实例。我调试了,我看到JDK正在调用该方法
javax.xml.bind.JAXBContext com.sun.xml.bind.v2.ContextFactory.createContext 通过反射,这就是创建类的时间。

我虽然这些类是由 GC 清理的。清理是 classLoader 的责任吗?

问题:有没有办法分析元空间对象?为什么我在元空间中有泄漏但在堆中没有泄漏?他们没有关系吗?这甚至可能吗?

为什么应用程序可以与 PermGen 一起正常工作,但不能与 Metaspace 一起工作?

最佳答案

我面临类似的问题。

就我而言,内存泄漏是由 JAXBContext.newInstance(...) 引起的调用。

解决方案:

  • 将此新实例包装为单例( https://github.com/javaee/jaxb-v2/issues/581 )或
  • 使用 -Dcom.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize=true VM 参数,如答案 Old JaxB and JDK8 Metaspace OutOfMemory Issue
  • 关于memory-leaks - 如何分析 Java 8 压缩类空间中的内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40346869/

    相关文章:

    html - 使用 Maven 插件从 XSD 生成 HTML 文档

    java - JAXB 列表标签创建内部类

    image - 有人可以验证这是 IE8 内存泄漏吗?

    c++ - 用于查找指针何时超出范围的程序和技术

    ios - Objective-C : GestureRecognizer in ViewController --> retain cycle?

    java - Java 8 lambda 和匿名内部类之间的性能差异

    java - 您能解释一下为什么第一个未包装的方法引用无法编译吗?

    objective-c - 多少内存泄漏(以字节为单位)可能是致命的

    java - 如何将Java集合转换为JAXB中XMLElement的属性?

    Java 8 原始流到集合的映射方法