[ 
https://issues.apache.org/jira/browse/CAMEL-23681?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Guillaume Nodet reassigned CAMEL-23681:
---------------------------------------

    Assignee: Guillaume Nodet

> Optimize Exchange memory pressure: copy-on-write headers and lazy 
> initialization
> --------------------------------------------------------------------------------
>
>                 Key: CAMEL-23681
>                 URL: https://issues.apache.org/jira/browse/CAMEL-23681
>             Project: Camel
>          Issue Type: Improvement
>          Components: camel-core
>            Reporter: Guillaume Nodet
>            Assignee: Guillaume Nodet
>            Priority: Major
>             Fix For: 4.21.0
>
>
> h2. Problem
> During Exchange routing, message copies (multicast, splitter, recipient-list, 
> pipeline processors) allocate new header maps via 
> {{ConcurrentHashMap.putAll()}} on every copy. For high-fanout EIPs this 
> creates significant memory pressure and GC load.
> h2. Analysis
> The Exchange lifecycle was analyzed for memory allocation patterns:
> *Header Map Copying:*
> - {{MessageSupport.copyFromWithNewBody()}} copies all headers on every 
> message copy
> - Multicast with N branches creates N full header map copies
> - Splitter with 1000 items creates ~1000 header map copies
> - Most copies only read headers — they never modify them
> *Lazy Headers:*
> - {{DefaultMessage.getHeader()}} and related read methods force-create the 
> headers map even when headers have never been set
> - Many pipeline processors only interact with the message body, not headers
> - Each unnecessary map creation wastes 200-400 bytes
> *Pooled Exchange Properties:*
> - {{DefaultPooledExchange.done()}} discards and recreates the properties map 
> on every reuse
> - For typical small properties maps, clearing and reusing is cheaper than 
> reallocating
> h2. Solution
> *1. Copy-on-Write Headers (Highest Impact)*
> Message copies now share the headers map reference until one side modifies 
> it. A {{CopyOnWriteHeadersMap}} wrapper defers cloning until the first 
> mutation, with lazy iterators for {{keySet()}} and {{entrySet()}} that only 
> trigger COW on {{Iterator.remove()}}.
> *2. Lazy Headers Initialization*
> {{getHeader()}} and related read methods return null without allocation when 
> headers have never been set.
> *3. Properties Map Reuse in Pooled Exchanges*
> {{DefaultPooledExchange.done()}} reuses cleared properties maps instead of 
> discarding them (threshold: 50 entries).
> h2. Expected Impact
> - Significant reduction in memory allocation for high-fanout EIPs (Multicast, 
> Splitter, RecipientList)
> - Zero behavioral change for existing routes
> - Backward compatible: no public API changes



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

Reply via email to