Perm or Metaspace OOME due to many duplicate JaxbAccessor classes
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=truesystem 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:
- Content from github.com is not included.JAXB-564
- The com.sun.xml.bind.v2.runtime.reflect.opt.Injector.inject call keeps generating accessor classes without trying to fetch prior ones from the classloader.
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 | |
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.