旧的JaxB和JDK8 Metaspace OutOfMemory问题 [英] Old JaxB and JDK8 Metaspace OutOfMemory Issue

查看:738
本文介绍了旧的JaxB和JDK8 Metaspace OutOfMemory问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在开发自10年以来开发的业务应用程序(100万+ LOC)。在切换到JDK8时,我们遇到了JDK8的元空间问题。这似乎与com.sun.xml.ws:webservices-rt:1.4(Metro 1.4)中引用的JaxB-Version有关。由于应用程序中的密集链接以及通过JaxB创建类/实例的传统,因此不需要简单地启动旧库。

We are working on a business application (1 million+ LOC) developed since 10+ years. While switching to JDK8 we get an issue with the metaspace of JDK8. This seems to be related to the JaxB-Version referenced in com.sun.xml.ws:webservices-rt:1.4 (Metro 1.4). Because of the intense linking in the application and legacy creation of classes/instances via JaxB it isn't simple to switch on the fly the old libraries.

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

Currently we are researching this issue. We created a sample programm that reproduces this behavior:

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模拟)
使用JDK7运行的记忆

JDK7 keeps the PermGenSpace clean. (Simulated with 16M PermGen) Memory of run with JDK7

使用JDK8,应用程序运行缓慢到OOM异常。 VisualVM捕获异常并使进程在最大可用Metaspace上运行。即使在这里,它在最长时间运行了很长一段时间后才会被卡住。 (使用16M Metaspace进行模拟)
使用JDK8运行的内存

Using JDK8 the application runs slowly to the OOM exception. The VisualVM catches the exception and keeps the process running on the maximum of available Metaspace. Even here it gets stucked after quite a while running on max. (Simulated with 16M Metaspace) Memory of run with JDK8

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

Has anyone some ideas how to get the garbage collectors legacy behavior, so we don't run into those out of memory issues? Or do you have any other ideas how to deal with this issue?

谢谢。

edit1:
运行参数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

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

=> heap dumps are generated while running.

VisualVM的可用内存未显示实际的最大元空间值。如果不受限制,则元空间不断增加,直到超出内存。

The Memory available of VisualVM does not show the real maximum metaspace value. If not limited the metaspace is constantly increasing untill memory is exceeded.

编辑2:

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

I have tried all available garbage collectors for JDK8. They all have the same issue.

编辑3:

由于JAXB之间的重叠耦合,在我们的实际应用中通过交换lib进行解决很困难&安培;我们应用的几个模块。因此,短期内需要修复垃圾收集器行为。从长远来看,已经计划了propper修复。

Solving by exchanging the libs is difficult in our real application because of heavy coupling between JAXB & several modules of our application. So a fix for the garbage collector behavior is needed for the short run. On the long run the propper fix is already planned.

推荐答案

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

We solved our current issue untill able to fix all occurances in our application by using the following VM-parameter:

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

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

I hope this will help others with similar issues...

这篇关于旧的JaxB和JDK8 Metaspace OutOfMemory问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆