Marvin Wright
Marvin Wright

Reputation: 31

Apache CXF Client Memory

We are having memory issues with our Apache CXF client, because of the service that we are connecting to requires WSSE security the port object cannot be shared across different clients of our application due to not being thread-safe. So we are using Apache Commons pool2 to pool x number of these objects. The service our CXF client connects to returns a very large and complex xml object and what we seem to notice using jProfiler is that the port object that we are pooling still has references into the complex response object that was returned, this means when we do a GC that memory is not being freed, when the service gets busy we see memory issues. Firstly is this normal for CXF and secondly is there a way to tell CXF to not hang on to these references and clean itself up?

As a very basic example this is how we are using the port after the pool was created when the application starts up

{
    webServicesPT webServicesPT = clientPool.getPort();  // calls borrowObject()

    try {
        webServicesPT.service();
    } finally {
        clientPool.returnPort(webServicesPT); // calls returnObject()
    }
}

Any help would be appreciated.

Thanks.

Upvotes: 3

Views: 1912

Answers (1)

Alexander Nemsadze
Alexander Nemsadze

Reputation: 91

We had exactly the same issue that you have described here. Actually the interesting part is that from the perspective of Apache CXF library everything is logical. The library uses WeakHashMap to store responseContext. The key used in the map is Thread object itself. So as your application is run on Application Server with thread pools and web service calls are made from different threads, last response is never deleted from the ClientImpl.responseContext WeakHashMap, as the Thread itself is never garbage collected. And as your responses are big, the memory is filled and it looks as it is some memory leak issue.

The solution is following: You have to clear responseContext manually when returning service port instance to pool using following code:

ClientProxy.getClient(webServicesPT).getResponseContext().clear();

Upvotes: 5

Related Questions