gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 04:20:26 30 4
gpt4 key购买 nike

一些上下文:我们已将 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/

    30 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com