On Nov 15, 2012, at 9:01 PM, Willem jiang <[email protected]> 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
[email protected] - http://dankulp.com/blog
Talend Community Coder - http://coders.talend.com