Old JaxB y JDK8 Metaspace OutOfMemory Issue

Estamos trabajando en una aplicación comercial (1 millón + LOC) desarrollada desde hace más de 10 años. Al cambiar a JDK8, tenemos un problema con el metaspace de JDK8. Esto parece estar relacionado con la versión JaxB a la que se hace referencia en com.sun.xml.ws:webservices-rt:1.4 (Metro 1.4). Debido a la intensa vinculación en la aplicación y la creación heredada de clases / instancias a través de JaxB, no es simple cambiar sobre la marcha las bibliotecas antiguas.

Actualmente estamos investigando este problema. Creamos un programa de muestra que reproduce este comportamiento:

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 mantiene limpio el PermGenSpace. (Simulado con 16M PermGen)Memoria de ejecución con JDK7

Usando JDK8, la aplicación se ejecuta lentamente a la excepción OOM. VisualVM detecta la excepción y mantiene el proceso ejecutándose en el máximo de Metaspace disponible. Incluso aquí se atasca después de un buen tiempo corriendo en max. (Simulado con 16M Metaspace)Memoria de ejecución con JDK8

¿Alguien tiene alguna idea de cómo obtener el comportamiento heredado de los recolectores de basura, para que no nos encontremos con problemas de memoria? ¿O tienes alguna otra idea sobre cómo lidiar con este problema?

Gracias.

edit1:Ejecute los parámetros JDK7:

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

=> No se crean volcados de almacenamiento dinámico

Ejecute los parámetros JDK8:

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

=> los volcados del montón se generan mientras se ejecuta.

La memoria disponible de VisualVM no muestra el valor máximo real de metaspace. Si no se limita, el metaespacio aumenta constantemente hasta que se excede la memoria.

editar 2:

He probado todos los recolectores de basura disponibles para JDK8. Todos tienen el mismo problema.

editar 3:

Resolver mediante el intercambio de libs es difícil en nuestra aplicación real debido al fuerte acoplamiento entre JAXB y varios módulos de nuestra aplicación. Por lo tanto, se necesita una solución para el comportamiento del recolector de basura a corto plazo. A la larga, la corrección adecuada ya está planificada.

Respuestas a la pregunta(3)

Su respuesta a la pregunta