Jiang Yunjun created AMQ-5348:
---------------------------------

             Summary: Network connector cause memory usage not count down
                 Key: AMQ-5348
                 URL: https://issues.apache.org/jira/browse/AMQ-5348
             Project: ActiveMQ
          Issue Type: Bug
    Affects Versions: 5.9.1, 5.9.0
            Reporter: Jiang Yunjun
            Priority: Critical


  We have two activeMQ servers , called A and B. A config network connector to 
B, and A is one way to B. We have a topic which is always sending to A, and a 
durable subscriber connecting to B. The problem is the "Memory percent used" in 
the web console do not decrease as the topic has successfully been consumed. 

     Our messages are not persistence,when we use only one activeMQ server 
,this problem is not an issue. 

     I had read the source code and debuged with adding some log info.I print 
the stack trace info at the 
org.apache.activemq.command.Message.incrementReferenceCount method and 
org.apache.activemq.command.Message.decrementReferenceCount method. 
And I found the difference between network connectors and standalone server. 

When using network connectors there will be another incrementReferenceCount 
call at: 

at 
org.apache.activemq.command.Message.incrementReferenceCount(Message.java:659) 
        at 
org.apache.activemq.filter.MessageEvaluationContext.getMessage(MessageEvaluationContext.java:53)
 
        at 
org.apache.activemq.command.NetworkBridgeFilter.matches(NetworkBridgeFilter.java:67)
 
        at 
org.apache.activemq.network.DemandForwardingBridgeSupport.suppressMessageDispatch(DemandForwardingBridgeSupport.java:1035)
 
        at 
org.apache.activemq.network.DemandForwardingBridgeSupport.serviceLocalCommand(DemandForwardingBridgeSupport.java:935)
 
        at 
org.apache.activemq.network.DemandForwardingBridgeSupport$2.onCommand(DemandForwardingBridgeSupport.java:177)
 
        at 
org.apache.activemq.transport.ResponseCorrelator.onCommand(ResponseCorrelator.java:116)
 
        at 
org.apache.activemq.transport.MutexTransport.onCommand(MutexTransport.java:50) 
        at 
org.apache.activemq.transport.vm.VMTransport.doDispatch(VMTransport.java:138) 
        at 
org.apache.activemq.transport.vm.VMTransport.dispatch(VMTransport.java:127) 
        at 
org.apache.activemq.transport.vm.VMTransport.oneway(VMTransport.java:104) 
        at 
org.apache.activemq.transport.MutexTransport.oneway(MutexTransport.java:68) 
        at 
org.apache.activemq.transport.ResponseCorrelator.oneway(ResponseCorrelator.java:60)
 
        at 
org.apache.activemq.broker.TransportConnection.dispatch(TransportConnection.java:1365)
 
        at 
org.apache.activemq.broker.TransportConnection.processDispatch(TransportConnection.java:884)
 
        at 
org.apache.activemq.broker.TransportConnection.iterate(TransportConnection.java:930)
 
        at 
org.apache.activemq.thread.PooledTaskRunner.runTask(PooledTaskRunner.java:133) 
        at 
org.apache.activemq.thread.PooledTaskRunner$1.run(PooledTaskRunner.java:48) 
        at 
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
        at 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
        at java.lang.Thread.run(Thread.java:744) 


and I see the source code in class 
org.apache.activemq.network.DemandForwardingBridgeSupport : 

 private boolean suppressMessageDispatch(MessageDispatch md, DemandSubscription 
sub) throws Exception { 
        boolean suppress = false; 
        // for durable subs, suppression via filter leaves dangling acks so we 
        // need to check here and allow the ack irrespective 
        if (sub.getLocalInfo().isDurable()) { 
            MessageEvaluationContext messageEvalContext = new 
MessageEvaluationContext(); 
            messageEvalContext.setMessageReference(md.getMessage()); 
            messageEvalContext.setDestination(md.getDestination()); 
            suppress = 
!sub.getNetworkBridgeFilter().matches(messageEvalContext); 
        } 
        return suppress; 
    } 

this method create a MessageEvaluationContext() , and in the  
"!sub.getNetworkBridgeFilter().matches(messageEvalContext);"  the 
MessageEvaluationContext's getMessage() method will be invoked and the 
incrementReferenceCount method there will be called. 
And the newly created messageEvalContext will be gc after the  
suppressMessageDispatch method is invoked over. But messageEvalContext.clear 
method is not called so the decrementReferenceCount is not called. 

I don't know whether it is a bug or just a nice design. 

BTW,we use activeMQ 5.9 and tried 5.9.1 ,5.10.0. 



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to