2014-06-16 45 views
3

我們的ActiveMQ消費進程耗盡內存並死亡。ActiveMQ消費者OutOfMemoryException

我們有一個ActiveMQ主題,有一個發件人和兩個接收者。從表面上看,所有的工作都很好---消息由兩個接收者發送並拾取,但最終我們耗盡了所有的內存。堆轉儲顯示LinkedList $ Node,AtomicReference,ActiveMQObjectMessage,MessageId和MessageDispatch的每個實例爲136.2萬個實例。同時,客戶端消息隊列全部爲空或幾乎爲空。我認爲1.362M可能在追蹤未確認消息的列表中。該主題被指定爲AUTO_ACKNOWLEDGE,所以我們試圖確認,但可能失敗。 (jmsSession = jmsConnection.createSession(false,Session.AUTO_ACKNOWLEDGE);)

堆轉儲顯示垃圾似乎與客戶的傳入消息緩衝存在適度數(幾千)相關聯。這似乎與我們設置用於發送和消費類似對象的玩具程序中積累的這些對象的數量一致。他們累積了一段時間,然後得到GC'd,並且記憶在玩具或失敗的程序中永遠不會顯着增長。

推測五種對象類型與ACKS相關聯是否正確?如果是這樣,儘管兩個消費者明顯完全消費,但是什麼會導致對象保留在此結構中?有什麼方法可以取消我們認爲已設置的AUTO_ACKNOWLEDGE?順便說一句,一個消費者是同步的,使用receive(),另一個是異步的,使用onMessage()。

一個可能令人誤解的症狀是ActiveMQ GUI顯示只有一次出隊的對象,儘管存在兩個消費者。玩具顯示每個隊列中有兩個出隊隊列。但是,該程序本身表示他們已閱讀了預期的次數。

// creating the async consumer. 

connAmq = createActiveMqConnection(); 
connAmq.start(); 
session = connAmq.createSession(true, Session.AUTO_ACKNOWLEDGE); 
Destination topic =  session.createTopic(appProperties.getActiveMqTopicQuotesName()); 
MessageConsumer consumer = session.createConsumer(topic); 
consumer.setMessageListener(this); 

public void onMessage(Message message) { 
    ...  
    try { 
      if (message instanceof ObjectMessage) { 
        ObjectMessage msg = (ObjectMessage)message; 
        if (msg instanceof Foo) { 
          Foo quote = (Foo)msg.getObject(); 
          ... 
        }  
      } 
    } 
    ... 
} 

// creating the sync consumer 

jmsConnection = mActiveMQConnectionFactory.createTopicConnection(); 

jmsConnection.start(); 
jmsSession = jmsConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); 
jmsDestination = jmsSession.createTopic(name); 
jmsMessageConsumer = jmsSession.createConsumer(jmsDestination); 


//the code for consuming looks like this for the synchronous consumer 
while(true) 
ObjectMessage m = (ObjectMessage) jmsMessageConsumer.receive(); 
if (m != null) 
    Process(m.getObject()); 
} 
+0

謝謝---但這是我的一個錯字。失敗的代碼設置事務值爲false。我簡化了,因爲它是一個變量,而不是字面的「錯誤」。它看起來像:session = connAmq.createSession(false,Session.AUTO_ACKNOWLEDGE); –

+0

session = connAmq.createSession(false,Session.AUTO_ACKNOWLEDGE); –

回答

0

至少在代碼片段給你創造了進行交易的異步消費者會話,但我沒有看到承諾的會議呼叫。交易位保留在代理的內存中,最終會耗盡代理的內存。

+0

嘿,你是對的。其中一位消費者的布爾控制事務行爲設置不正確。問題解決了。謝啦。 –