Uploaded image for project: 'Camel'
  1. Camel
  2. CAMEL-10048

Memory leak in RoutingSlip

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 2.16.2, 2.16.3, 2.17.0, 2.17.1
    • Fix Version/s: 2.16.4, 2.17.2, 2.18.0
    • Component/s: camel-core
    • Labels:
    • 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)

    • Estimated Complexity:
      Unknown
    • Flags:
      Important

      Description

      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 the 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.

        Attachments

        1. RoutingSlipMemoryLeakTest.java
          4 kB
          Arseniy Tashoyan

          Issue Links

            Activity

              People

              • Assignee:
                davsclaus Claus Ibsen
                Reporter:
                tashoyan Arseniy Tashoyan
              • Votes:
                0 Vote for this issue
                Watchers:
                3 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:

                  Time Tracking

                  Estimated:
                  Original Estimate - 48h
                  48h
                  Remaining:
                  Remaining Estimate - 48h
                  48h
                  Logged:
                  Time Spent - Not Specified
                  Not Specified