JAXB works fine for marshalling and unmarshalling. Because it can be slow to create marshallers and unmarshallers, using pools for them (based on contextPath) seems a reasonable approach. However, it appears that Unmarshaller holds onto objects after it is done. If it was passed a very large document, then it may hold onto a lot of memory if that particular Unmarshaller isn’t reused for a while. Is there a way to cause JAXB to release the objects it processed?
JAXBContext jaxBContext = JAXBContext.newInstance(contextPath, loader);
Unmarshaller unMarshaller = jaxBContext.createUnmarshaller();
...
responseObject = unmarshaller.unmarshal( new StreamSource( new StringReader( xml ) ) );
There are examples online of pooling approaches like this (e.g. one at apache: JAXBUtils.java). Most don’t seem to do anything special when they put an Unmarshaller back in the pool.
Update: This appears to be a bug in JAXB: Post-Unmarshall Object Retention. The similar bug in Marshall was fixed earlier so it’s in recent versions of JAXB. So now I’m wondering (a) if there’s a workaround for this issue with Unmarshaller (b) which version of Java6 this fix is/will be included in.
One workaround that occurs to me is to pool the JAXBContext rather than the Un/Marshaller. Doing some quick timings, it seems that the time taken for creating a Un/Marshaller is negligible compared to the time taken to create a JAXBContext from a contextPath. And by holding only a reference to the JAXBContext in the pool, then the Unmarshaller should be freed up, which hopefully allows the GC to reclaim its memory along with that of the doc that the Unmarshaller was holding onto due to the jaxb bug.