Old JaxB und JDK8 Metaspace OutOfMemory Issue

Wir arbeiten an einer Geschäftsanwendung (1 Million + LOC), die seit über 10 Jahren entwickelt wurde. Beim Umstieg auf JDK8 tritt ein Problem mit dem Metaspace von JDK8 auf. Dies scheint mit der JaxB-Version zu tun zu haben, auf die in com.sun.xml.ws:webservices-rt:1.4 (Metro 1.4) verwiesen wird. Aufgrund der intensiven Verknüpfung in der Anwendung und der Legacy-Erstellung von Klassen / Instanzen über JaxB ist es nicht einfach, die alten Bibliotheken im Handumdrehen einzuschalten.

erzeit untersuchen wir dieses Problem. Wir haben ein Beispielprogramm erstellt, das dieses Verhalten reproduziert:

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 hält den PermGenSpace sauber. (Simuliert mit 16M PermGen)Speicher des Laufs mit JDK7

Mit JDK8 wird die Anwendung langsam zur OOM-Ausnahme ausgeführt. Die VisualVM fängt die Ausnahme ab und hält den Prozess auf dem Maximum des verfügbaren Metaspace. Auch hier bleibt es nach einiger Zeit hängen und läuft auf max. (Simuliert mit 16M Metaspace)Speicher des Laufs mit JDK8

Hat jemand eine Idee, wie man das Vermächtnisverhalten der Garbage Collectors erlangt, damit wir nicht auf Probleme mit unzureichendem Arbeitsspeicher stoßen? Oder haben Sie andere Ideen, wie Sie mit diesem Problem umgehen können?

Vielen Dank

edit1:Laufparameter JDK7:

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

=> Es werden keine Heap-Dumps erstellt

Laufparameter JDK8:

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

=> Heap-Dumps werden während der Ausführung generiert.

Der in VisualVM verfügbare Speicher zeigt nicht den tatsächlichen maximalen Metaspace-Wert an. Wenn nicht beschränkt, nimmt der Metaspace ständig zu, bis der Arbeitsspeicher überschritten wird.

edit 2:

Ich habe alle verfügbaren Garbage Collectors für JDK8 ausprobiert. Sie haben alle das gleiche Problem.

edit 3:

Lösen durch Austausch der Bibliotheken ist in unserer realen Anwendung aufgrund der starken Kopplung zwischen JAXB und mehreren Modulen unserer Anwendung schwierig. Daher ist kurzfristig eine Korrektur des Garbage Collector-Verhaltens erforderlich. Auf lange Sicht ist der richtige Fix bereits geplant.

Antworten auf die Frage(6)

Ihre Antwort auf die Frage