Perm or Metaspace OOME due to many duplicate JaxbAccessor classes

Solution Verified - Updated

Environment

  • JBoss Enterprise Application Platform (EAP)

Issue

  • We see a perm or metaspace OOME and the heap dump shows many duplicate JaxbAccessor classes (such as com.package.name.Class$$JaxbAccessorF_variablename) in our application classloader.

  • The OOME is hit in a call like the following:

    |- at java.lang.OutOfMemoryError.<init>()V (OutOfMemoryError.java:48)
    |- at java.lang.ClassLoader.defineClass1(Ljava/lang/String;[BIILjava/security/ProtectionDomain;Ljava/lang/String;)Ljava/lang/Class; (Native Method)
    |- at java.lang.ClassLoader.defineClass(Ljava/lang/String;[BIILjava/security/ProtectionDomain;)Ljava/lang/Class; (ClassLoader.java:760)
    |- at java.lang.ClassLoader.defineClass(Ljava/lang/String;[BII)Ljava/lang/Class; (ClassLoader.java:642)
    |- at sun.reflect.GeneratedMethodAccessor242.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; (Unknown Source)
    |- at sun.reflect.DelegatingMethodAccessorImpl.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; (DelegatingMethodAccessorImpl.java:43)
    |- at java.lang.reflect.Method.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; (Method.java:497)
    |- at com.sun.xml.bind.v2.runtime.reflect.opt.Injector.inject(Ljava/lang/String;[B)Ljava/lang/Class; (Injector.java:181)
    |- at com.sun.xml.bind.v2.runtime.reflect.opt.Injector.inject(Ljava/lang/ClassLoader;Ljava/lang/String;[B)Ljava/lang/Class; (Injector.java:85)
    
  • Code similar to the following that performs a JAXB XML translation results in endlessly creating new classes:

    StringWriter sw = new StringWriter();
    JAXBContext jaxbContext = JAXBContext.newInstance(myObject.getClass());
    Marshaller marshal = jaxbContext.createMarshaller();
    marshal.marshal(myObject, sw);
    

Resolution

To avoid this issue:

  • Upgrade to JAXB 2.1.13+

  • Set the -Dcom.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize=true system property as a workaround

  • Cache the JAXBContext. For the best performance you should have just one instance of JAXBContext in your whole application. For example:

        class MyServlet extends HttpServlet {
            static final JAXBContext context = initContext();
    
            private static JAXBContext initContext() {
                return JAXBContext.newInstance(Foo.class,Bar.class);
            }
        }
    

    To unmarshall/marshall/validate a document, create a new Unmarshaller/Marshaller/Validator from the context as follows:

    public void doGet( HttpServletRequest req, HttpServletResponse ) {
        Unmarshaller u = context.createUnmarshaller();
        u.unmarshal(...);
    }
    

    See Content from jaxb.java.net is not included.Unofficial JAXB Guide.

Root Cause

The following are causes of this issue:

Diagnostic Steps

Heap dump analysis:

  • Check for multiple instances of one of the following:
    • org.apache.cxf.common.jaxb.JAXBContextCache$2.
    • com.sun.xml.bind.v2.runtime.JAXBContextImpl

e.g. Running following OQL

select * from com.sun.xml.bind.v2.runtime.JAXBContextImpl
Class Name                                              | Shallow Heap | Retained Heap
---------------------------------------------------------------------------------------
com.sun.xml.bind.v2.runtime.JAXBContextImpl @ 0x9cc507a0|           96 |       280,904
com.sun.xml.bind.v2.runtime.JAXBContextImpl @ 0x9cb957b8|           96 |       396,288
com.sun.xml.bind.v2.runtime.JAXBContextImpl @ 0x9c1e9c70|           96 |     1,301,576
com.sun.xml.bind.v2.runtime.JAXBContextImpl @ 0x9bd52078|           96 |     1,730,776
com.sun.xml.bind.v2.runtime.JAXBContextImpl @ 0x9b8d8728|           96 |       956,240
com.sun.xml.bind.v2.runtime.JAXBContextImpl @ 0x9b4c2710|           96 |        47,680
com.sun.xml.bind.v2.runtime.JAXBContextImpl @ 0x9afd7958|           96 |       248,000
com.sun.xml.bind.v2.runtime.JAXBContextImpl @ 0x9aaac198|           96 |       264,024
com.sun.xml.bind.v2.runtime.JAXBContextImpl @ 0x9e62ca30|           96 |        74,472
com.sun.xml.bind.v2.runtime.JAXBContextImpl @ 0x9da0df98|           96 |       335,904
com.sun.xml.bind.v2.runtime.JAXBContextImpl @ 0x9d613f18|           96 |     1,301,760
com.sun.xml.bind.v2.runtime.JAXBContextImpl @ 0x9ceba6e8|           96 |     1,732,208
Total: 26 of 82 entries; 56 more                        |              |              
Components
Category

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.