camel-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Daniel Kulp <dk...@apache.org>
Subject Re: svn commit: r1409651 - in /camel/trunk: components/camel-cxf/src/test/java/org/apache/camel/component/cxf/ examples/camel-example-loan-broker/src/main/java/org/apache/camel/loanbroker/webservice/version/
Date Fri, 16 Nov 2012 18:35:43 GMT

On Nov 15, 2012, at 9:01 PM, Willem jiang <willem.jiang@gmail.com> wrote:
> Thanks for sharing this. I check the code of CXF, the ClientProxy has the finalize()
method, I think JDK calling it before GC is kicked[1].
> " After a finalizer is invoked, objects are not freed right away. This is because a finalizer
method can resurrect an object by storing the this pointer somewhere so that the object once
again has references. Thus, after finalize() is called, the garbage collector must once again
determine that the object is unreferenced before it can garbage-collect it. "
> 
> But I still not quite sure why the finalize() is called when the proxy invoke method
is called, maybe IBM JDK GC is too aggressive.  

The IBM JDK/JIT is doing some really awesome stack analysis and removing references off the
stack once it knows it's not needed in the current stack frame anymore.   This is AWESOME
and something I've wished the JDK's would do for years.    This opens up a bunch of potential
optimizations in CXF that I haven't bothered pursing due to the lack of support for this in
any of the JDK's I've ever tested with.   As an example, if you have CXF code like:

MyBigJAXBObject obj = createSomeHugeTreeOfJAXBThings(….);
MyResult result = client.sendObject(obj);

With CXF, if we are careful, once we are done writing "obj" out to streams, we could discard
it (remove the contents list from the request message) which could allow the gc to completely
remove that from memory.  However, I never pursued that because with all the other JDK's,
since the reference to it is on the stack, (both as the "obj" above and also as params in
the "invoke" method of the proxy handler)  it wouldn't get collected.   With the IBM JDK,
this looks like it may actually be possible now.    


In any case, what's happing is that in ClientProxy.invoke(…), we're doing something like:


public Object invoke(….) {
    …..
    return clientImpl.invokeSync(….);
}

Once the invokeSync is entered, the "this" for the ClientProxy isn't needed on the stack anymore
and thus the stack is cleaned up.   Likewise, the original call to "client.echo(…)" results
in the "client" not being needed so that is removed from the stack.   Thus, ClientProxy has
no references and can be removed.

I've made a "workaround" in ClientProxy to do:

public Object invoke(….) {
    …..
    Object obj = clientImpl.invokeSync(….);
    obj = adjustObject(obj);
    return obj;
}
protected Object adjustObject(obj) {
    return obj;
}

which seems to work.   The call to "invokeSync" must keep the "this" reference on the stack
so it can call the virtual adjustObject method after the return.   That seems to allow things
to work significantly better. 

In any case, I now have all the CXF unit tests running "most of the time" with the IBM7 JDK.
  There are some problems in the ws-security system tests with some of the GSM algorithms.
 I'll need to follow up with Colm about those.    There are a couple other random failure
stragglers that I'm trying to look at, but I think I got the big ones.   Many of the issues
were related to things in WSDL/IDL being generated in different orders, type names being picked
up different due to the difference in the reflection ordering, etc… Those were definitely
all test issues.   Another class of stuff is related to the garbage collector being very aggressive.
   The IBM gc apparently runs very often so discarded clients are collected sooner resulting
in their close being called sooner.   For "decoupled" clients, that then shuts down the decoupled
port which could then result in the "next" test that wants to use that port to fail.   I've
fixed as many of those as I could be making sure each test:

1) calls the close() on the client specifically when done.   The tests should cleanup after
themselves.   
2) Make sure each test dynamically grabs it's own ports.

I've likely missed a bunch of those, but the tests are now running again which is a good start.

Anyway, the next snapshot builds should have a bunch of fixes in place that should hopefully
work better.      I likely won't have time to look into the camel side of things next week,
but possibly after Thanksgiving unless someone beats me to it.


-- 
Daniel Kulp
dkulp@apache.org - http://dankulp.com/blog
Talend Community Coder - http://coders.talend.com


Mime
View raw message