Hi,

Sergey Beryozkin-5 wrote:
> 
> On Fri, Aug 6, 2010 at 11:02 AM, Oliver Schmitz-Hennemann <
> [email protected]> 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.
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?)
 - Enable CXF to keep only one JAXB context (and not to throw it away) - do
not know how to do that
 - 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
 - Do not use JAXB with CXF on a website with significant load

If I can do anything to help resolving this, please let me know.

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.

Reply via email to