camel-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Arseniy Tashoyan (JIRA)" <>
Subject [jira] [Updated] (CAMEL-10048) Memory leak in RoutingSlip
Date Sat, 11 Jun 2016 21:48:20 GMT


Arseniy Tashoyan updated CAMEL-10048:

Adding a unit test to reproduce

> Memory leak in RoutingSlip
> --------------------------
>                 Key: CAMEL-10048
>                 URL:
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-core
>    Affects Versions: 2.16.2, 2.16.3, 2.17.0, 2.17.1
>         Environment: java version "1.8.0_51"
> Java(TM) SE Runtime Environment (build 1.8.0_51-b16)
> Java HotSpot(TM) 64-Bit Server VM (build 25.51-b03, mixed mode)
>            Reporter: Arseniy Tashoyan
>              Labels: core, leak, routing
>         Attachments:
>   Original Estimate: 48h
>  Remaining Estimate: 48h
> RoutingSlip has a cache of error handlers implemented as a ConcurrentHashMap. This map
stores error handlers as values, and uses some synthetic objects as keys. For some kind of
destinations provided in routing slip, map lookup operation does not work. Hence, new error
handlers are always added to the map and existing error handlers never reused. Finally, the
program runs out of memory.
> The synthetic keys are actually instances of class RoutingSlip.PreparedErrorHandler.
Such key is based on two objects: RouteContext and destination Processor. Neither RouteContext
nor Processor do not require their implementations to provide equals() and hashCode() methods.
Strictly speaking, caching implementation in RoutingSlip is incorrect, because it uses hash
map in the discouraged way. However, for some cases it works.
> The problem occurs when routing slip contains a 'sync' destination, in other words -
destination is a Processor that does not implement AsyncProcessor interface. RoutingSlip determines
destination producer via ProducerCache.doInAsyncProducer(), and the latter uses AsyncProcessorConverterHelper.convert()
method. This method creates new instance of Processor for every processor that is not an instance
of AsyncProcessor. This is where problem hides: new object has different hash code (defined
by Object.hashCode()) and new object isn't equal to the object used as a key in the hash map
(well, Object.equals()). Finally, new key for the hash map is calculated, lookup operation
cannot find this key in the hash map, new key-value pair is put into the hash map.

This message was sent by Atlassian JIRA

View raw message