Lars Haugaard Kristensen created CAMEL-22691:
------------------------------------------------

             Summary: Memory leak in CXF producer
                 Key: CAMEL-22691
                 URL: https://issues.apache.org/jira/browse/CAMEL-22691
             Project: Camel
          Issue Type: Bug
          Components: camel-cxf
    Affects Versions: 4.16.0, 4.14.2, 4.10.7
         Environment: Camel Spring Boot 4.10.3
Red Hat OpenJDK 17
REST component is "platform-http"
Embedded web server is Tomcat
OS is RHEL 8.10
            Reporter: Lars Haugaard Kristensen
         Attachments: cxf-leak-jprofiler.png

Zulip topic: [#camel > Memory leak in CXF 
client|https://camel.zulipchat.com/#narrow/channel/257298-camel/topic/Memory.20leak.20in.20CXF.20client/with/555530583]

I'm seeing a memory leak in a production system, leading to OOM. The 
application is based on Spring Boot, Tomcat, and platform-http as the rest 
component.

I use a REST consumer that performs some mapping, then calls a SOAP service 
using CXF. Internally in CXF, a map from Thread to responseContext is not 
cleaned up when the exchange completes, and the map simply grows, and entries 
are not garbage collected (ref. 
org.apache.cxf.endpoint.ClientImpl#responseContext).

I have put together a reproducer which is available on Github:

[https://github.com/Larshk/camel-cxf-leak]

The behavior can be reproduced in Camel versions 4.10.7, 4.14.2, and 4.16.0. I 
can work around the problem by setting the following property, which is not 
ideal:

{{spring.task.execution.pool.allow-core-thread-timeout=false}}

I found this (old) CXF issue which seems somewhat related:

https://issues.apache.org/jira/browse/CXF-7710

By debugging I see that org.apache.cxf.endpoint.ClientImpl#setResponseContext 
is called on two separate threads during the exchange processing, such as:
{noformat}
Response context set on thread task-1, responseContext.size() after: 13
Response context set on thread default-workqueue-4, responseContext.size() 
after: 13
Response context set on thread default-workqueue-4, responseContext.size() 
after: 13
{noformat}
In this case the "task-1" thread is created by an executor of type:

{{org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor}}

This executor is by default configured to un-alive idle core threads. When 
there is low activity, threads are terminated and new are created when needed, 
leading to new entries in the responseContext map.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to