java - 旧的 JaxB 和 JDK 8 元空间内存不足问题

标签 java jaxb java-8 out-of-memory java-metro-framework

我们正在开发一个 10 多年以来开发的业务应用程序(超过 100 万个 LOC)。在切换到 JDK8 时,我们遇到了 JDK8 元空间的问题。这似乎与 com.sun.xml.ws:webservices-rt:1.4 (Metro 1.4) 中引用的 JaxB-Version 有关。由于应用程序中的紧密链接以及通过 JaxB 创建类/实例的遗留问题,因此动态切换旧库并不容易。

目前我们正在研究这个问题。我们创建了一个重现此行为的示例程序:

import java.io.ByteArrayInputStream;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class X
{
  private static final String XML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><x test=\"test\" />";

  @XmlAttribute
  String test;

  public static void main( String[] args ) throws JAXBException, InterruptedException
  {
    System.out.println("start");

    while ( true )
    {
      JAXBContext jc = JAXBContext.newInstance( X.class );
      Unmarshaller unmarshaller = jc.createUnmarshaller();
      X object = (X) unmarshaller.unmarshal( new ByteArrayInputStream( XML.getBytes() ) );
      System.out.println( object.test );
    }
  }
}

JDK7 保持 PermGenSpace 干净。 (用 16M PermGen 模拟) Memory of run with JDK7

使用JDK8应用程序运行缓慢出现OOM异常。 VisualVM 捕获异常并保持进程在最大可用元空间上运行。即使在这里,在最大运行一段时间后它也会卡住。 (模拟16M元空间) Memory of run with JDK8

有没有人知道如何获得垃圾收集器的遗留行为,这样我们就不会遇到那些内存不足的问题?或者您有其他想法如何处理这个问题?

谢谢。

编辑1: JDK7运行参数:

-XX:+TraceClassLoading -XX:+TraceClassUnloading -XX:MaxPermSize=16M -XX:PermSize=1M -XX:+UseParallelOldGC -XX:+HeapDumpOnOutOfMemoryError

=> 没有创建堆转储

JDK8运行参数:

-XX:+TraceClassLoading -XX:+TraceClassUnloading -XX:MaxMetaspaceSize=16M -XX:MetaspaceSize=1M -XX:+UseParallelOldGC -XX:+HeapDumpOnOutOfMemoryError

=> 堆转储在运行时生成。

VisualVM 的可用内存不显示真正的最大元空间值。如果没有限制,元空间会不断增加,直到超出内存。

编辑 2:

我已经为 JDK8 尝试了所有可用的垃圾收集器。他们都有同样的问题。

编辑 3:

在我们的实际应用程序中,通过交换库来解决问题是很困难的,因为 JAXB 和我们应用程序的几个模块之间存在严重耦合。因此,短期内需要对垃圾收集器行为进行修复。从长远来看,适当的修复已经计划好了。

最佳答案

我们解决了当前的问题,直到能够使用以下 VM 参数修复应用程序中的所有问题:

-Dcom.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize=true

我希望这能帮助其他有类似问题的人...

关于java - 旧的 JaxB 和 JDK 8 元空间内存不足问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33255578/

相关文章:

java - Android Volley POST 请求返回错误 400(错误请求)

java - Eclipse,AppEngine : java. lang.RuntimeException : Cannot get the System Java Compiler. 请使用 JDK,而不是 JRE

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

java - 如何屏蔽自动生成的 swagger java 类中的任何参数

java - 在特定列中显示数据

java - JAXB 不为空 xs :element tag 创建类

java - 无法使用 @XmlElementWrapper 解码与父元素具有相同名称的 XML 相同元素列表

java - 使用混合类型时编码 XML 没有子级

java - 使用祖 parent 接口(interface)的默认方法

java - 转换逻辑以使用 Java 8 Streams