Uploaded image for project: 'ActiveMQ'
  1. ActiveMQ
  2. AMQ-6066

Performance issue in OrderedPendingList

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 5.12.1
    • Fix Version/s: 5.13.0, 5.12.2
    • Component/s: Broker
    • Labels:
      None

      Description

      I have updated my application from ActiveMQ 5.3 to 5.11.1 and have noticed a serious performance degregation. Running a number of jstacks I can see the broker is often stuck here:

      "Queue:master-items" Id=122 RUNNABLE
      	at org.apache.activemq.broker.region.cursors.OrderedPendingList.contains(OrderedPendingList.java:144)
      	at org.apache.activemq.broker.region.Queue.doPageInForDispatch(Queue.java:1930)
      	at org.apache.activemq.broker.region.Queue.pageInMessages(Queue.java:2119)
      	at org.apache.activemq.broker.region.Queue.iterate(Queue.java:1596)
      	-  locked java.lang.Object@253c3089
      	at org.apache.activemq.thread.DedicatedTaskRunner.runTask(DedicatedTaskRunner.java:112)
      	at org.apache.activemq.thread.DedicatedTaskRunner$1.run(DedicatedTaskRunner.java:42)
      
      	Number of locked synchronizers = 1
      	- java.util.concurrent.locks.ReentrantReadWriteLock$NonfairSync@2eb46567
      

      For this specific queue in my application, there were a large number of items in it.. around 100,000. However I noticed the code for contains has:

          public boolean contains(MessageReference message) {
              if (message != null) {
                  for (PendingNode value : map.values()) {
                      if (value.getMessage().equals(message)) {
                          return true;
                      }
                  }
              }
              return false;
          }
      

      This will obviously be very slow. Given the Map is keyed by message ID, can't we do a .contains(message.getMessageId()) instead? I noticed the remove() method does this. I changed the code to do this:

      @Override
      public boolean contains(MessageReference message) {
          if (message != null) {
              return map.containsKey(message.getMessageId());
          }
          return false;
      }
      

      I got a speedup for my test which now takes 29 minutes from 41 minutes. Can we get this change in to the upcoming 5.13 release (pretty please??) It is a tiny (but very important) change for us.. many thanks.

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                cshannon Christopher L. Shannon
                Reporter:
                sits David Sitsky
              • Votes:
                0 Vote for this issue
                Watchers:
                6 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: