cxf-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sergey Beryozkin <sberyoz...@gmail.com>
Subject Re: REST web service loading many classes for each request CXF 2.2.6 and jaxb-impl 2.1.5
Date Thu, 12 Aug 2010 16:01:16 GMT
Hi

On Thu, Aug 12, 2010 at 4:15 PM, Stefan Schubert <mail@ste-net.de> wrote:

>
> Hi,
>
>
> Sergey Beryozkin-5 wrote:
> >
> > On Fri, Aug 6, 2010 at 11:02 AM, Oliver Schmitz-Hennemann <
> > oli99sc@googlemail.com> wrote:
> >
> >> we have implemented a REST webservice using CXF 2.2.6 and jaxb 2.1.5
> >> running
> >> in a tomcat 6.0.10.
> >> We are experiencing some serious problems concerning perm gen memory
> >> usage
> >> induced by continuously loading classes.
> >> Having traced around through the code we now know that the problem is
> >> induced by the fact, that the JaxbContext and within that some Injector
> >> implementations are only stored in WeakReferences. This each GC removes
> >> both. So, each Request after a GC will create a lot of classes.
> >>
> >
> > I think there may've been some issue fixed in CXF 2.2.6/7 related to a
> > possible leak.
> > Dan pointed out the other day that WeakRefs don't make a difference in
> > this
> > case given that JAXBContexts link to the Classes, so that should not
> cause
> > perm gen issues;
> >
>
> yes, of course WeakRefs make a difference. They do when the underlying
> technology (JAXB) has a memory leak as well.
>
> Let me clarify the problem:
> If a GC occurs, WeakRefs throw away the JAXBContext. So on the next
> occasion
> (where occasion could be one of billions of calls to a CXF/JAXB api) the
> JAXBContext has to be rebuilt from scratch.
>

JAXBElementResolver has two maps, one for keeping package contexts, another
one for class-specific contexts.
In the second one weak-refs do not work given that JAXBContexts reverse link
to Class keys, but yeah I can see now package contexts can be released
often, I thought they were keyed by classes too.


> JAXB (specifically
> com.sun.xml.bind.v2.runtime.reflect.opt.AccessorInjector)
> calls com.sun.xml.bind.v2.runtime.reflect.opt.Injector#find to try, if it
> already created a field or method accessor class. If not it injects a new
> one into the class loader via
> com.sun.xml.bind.v2.runtime.reflect.opt.Injector#inject.
> The problem is now that #inject caches the generated accessor in the
> Injector and find only looks into the Injector (and never again into the
> class loader, where it used to define the class). But once a GC occurs the
> Injector throws itself away, too (caching itself in some weak map).
>
> So it happens that each REST api call after a GC occurred a hundred new
> classes are created by JAXB - because JAXB on low-level forgets the classes
> it defines (and keeps them on high-level) and CXF forgets the JAXBContext
> so
> that the high-level memory of JAXB is erased as well.
>
> There are three possible solutions:
>  - Fix the Injector: Actually very easy and my favorite solution. Just let
> the Injector look into the class loader as well when it cannot find the
> class in its own memory. BUT to have a bug fixed in JAXB actually sounds
> scary, how long would that take to get into a version?)
>

Not realistic I guess.


>  - Enable CXF to keep only one JAXB context (and not to throw it away) - do
> not know how to do that
>

It is possible but may be problematic due to JAXRS allowing root resources
returning Object subresources so it is not possible to reliably introspect
all the service classes and build a single context. Perhaps there could be
an option there anyway for doing such an introspection. In fact you can do
it right now, use DataBindingProvider and delegate to CXF JAXB DataBinding,
please check the docs, there should be a link to the test showing how to do
it.


>  - Use a workaround to disable bytecode generation by JAXB
> (-Dcom.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize=true) --> disables
> the whole bytecode magic Injector stuff and just does reflection - probably
> with a slight performance impact
>

it is a possibility


>  - Do not use JAXB with CXF on a website with significant load
>
>
two more options :
- get rid of WeakHashMaps and use plain HashMaps
- register a custom JAXBElementProvider, override methods to do with
creating JAXB contexts and keep them in hash maps

If I can do anything to help resolving this, please let me know.
>
> would you consider supplying a patch to do with changing WeakHashMaps to
HashMaps in AbstractJaxbProvider ? This could be a good intermediate
solution ?

thanks, Sergey


> Cheers
> Stefan
> --
> View this message in context:
> http://cxf.547215.n5.nabble.com/REST-web-service-loading-many-classes-for-each-request-CXF-2-2-6-and-jaxb-impl-2-1-5-tp2266472p2473327.html
> Sent from the cxf-user mailing list archive at Nabble.com.
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message