Memory leaks 如何分析Java8压缩类空间中的内存泄漏?

Memory leaks 如何分析Java8压缩类空间中的内存泄漏?,memory-leaks,jaxb,java-8,out-of-memory,metadata,Memory Leaks,Jaxb,Java 8,Out Of Memory,Metadata,一些上下文:我们已经将web应用程序的环境从运行在Java 7上升级到运行在Java 8和Tomcat 8上(64位arch,堆大小约为2 GB,PermGen大小=256 MB,对元空间大小没有限制)。过了一会儿,我们开始出现以下错误: java.lang.OutOfMemoryError:压缩的类空间 这意味着UseCompressedClassPointers所需的空间超过了CompressedClassSpaceSize。当时VisualVM显示了2GB的元空间大小 现在使用Visual

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

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

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

现在使用VisualVM工具,我们可以看到元空间的大小随着每个请求不断增加,大约为3MB,但是堆似乎没有这样做。堆的使用有一个锯齿形,在每次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清理的。类加载器负责清理吗


问题:有没有办法分析元空间对象?为什么我在元空间中有漏洞而在堆中没有?他们不相关吗?这可能吗


为什么该应用程序可以与PermGen配合使用而不能与Metaspace配合使用?

我面临着类似的问题

在我的例子中,内存泄漏是由
JAXBContext.newInstance(…)
invoke引起的

解决方案:


  • 将此新实例包装为singleton()或
  • 使用
    -Dcom.sun.xml.bind.v2.bytecode.classtailer.noOptimize=true
    VM参数,如答案中所示

我遇到了类似的问题,在setenv.sh中添加了-Dcom.sun.xml.bind.v2.bytecode.classtailer.noOptimize=true作为JVM OPT参数,它解决了OOM元空间问题。

您没有“PermGen size=256 MB”,因为Java 8没有PermGen。但无论如何,元空间中的数据与类关联,因此首先要查找的是
Class
实例。即使它们不占堆的很大一部分,但如果它们的数量在增长而未被收集,它们也可能是元空间增长的原因。看起来,…进行堆转储,分析是否有泄漏的类或类加载器。@Bassam:您最终使用了singleton选项还是使用了noOptimize标志?谢谢。我想知道为什么类加载器一次又一次地加载类。我还没有时间检查JAXB代码。“将这个新实例包装为singleton()”这个方法有什么缺点吗?使用“-Dcom.sun.xml.bind.v2.bytecode.classtailer.noOptimize=true”的替代方案似乎降低了性能。我正在尝试在这两个选项中进行选择,我看到这会给出错误消息,java.net已经关闭。我假设这张票是用于JAXB项目的。有人知道怎么读那页内容吗?我在上查看了当前的JAXB github项目——但是,找不到这个特定的问题,因此没有使用单例的折衷方案options@Bassam:你最终是使用了singleton选项还是使用了noOptimize标志?@anjanb:singleton是最好的选择,结果发现泄漏存在于Java 7及更早版本中,但是我们没有注意到它,因为它是grabage收集的。我正在为org.jgroups.logging.Log4J2LogImpl获得压缩的类空间。错误:第95行如何解决org.jgroups.logging.Log4J2LogImp的问题