我是 Apache ActiveMQ 的新手,在 ActiveMQ 中發送和存儲大量大消息(最大的大約 100mb)時遇到了一些麻煩。消息是持久的,所以據我所知它們存儲在硬盤驅動器上,而不是內存中。但奇怪的是,當數據庫大?。↘ahaDB 文件夾)達到 2.8Gb(4Gb jvm 堆的 70%)時,ActiveMQ 崩潰了。似乎 ActiveMQ 仍然將所有消息存儲在內存中。我需要首先存儲所有消息,然后我將全部使用它們。我的配置 activemq.xml<policyEntry queue=">" producerFlowControl="false" memoryLimit="100MB"> <pendingQueuePolicy> <fileQueueCursor /> </pendingQueuePolicy></policyEntry>...<systemUsage> <systemUsage> <memoryUsage> <memoryUsage percentOfJvmHeap="70" /> </memoryUsage> <storeUsage> <storeUsage limit="100 gb"/> </storeUsage> <tempUsage> <tempUsage limit="50 gb"/> </tempUsage> </systemUsage></systemUsage>...<transportConnectors> <transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=204857600"/></transportConnectors>這就是我如何用 java 發送消息。Try-with-resources 關閉所有。try (Connection conn = queueConnFactory.createConnection(); Session session = conn.createSession(true, Session.AUTO_ACKNOWLEDGE); MessageProducer producer = session.createProducer(getTargetQueue())) { ObjectMessage message = session.createObjectMessage(transferMessage); producer.send(message); }
1 回答

慕仙森
TA貢獻1827條經驗 獲得超8個贊
在這一點上,我沒有看到任何內存泄漏的證據。僅僅因為代理內存不足并不意味著存在泄漏。您可能根本沒有為您的用例提供足夠的 JVM 堆。
此外,僅僅因為代理使用某種數據庫(即 KahaDB)將消息存儲到磁盤并不意味著代理很像數據庫。代理仍將盡可能多地在內存中存儲消息數據,盡管消息與您的斷言相反已持久保存到磁盤。一旦將消息數據寫入磁盤就從內存中清除消息數據,然后在消費者需要時立即從磁盤重新加載它,這將是非常低效的。還有一個問題是代理必須在不將它們寫入磁盤的情況下跟蹤非持久性消息。
如果您只是要存儲所有數據然后稍后檢索它,那么最好只使用數據庫,因為數據庫更適合這種用例。消息代理通常更適合消費者與生產者同時活動且消息不在代理上建立但在到達后立即發送給消費者的用例。
您的代碼片段可能是一種反模式。JMS 連接是線程安全的,可以重復使用。為每條發送的消息打開和關閉連接是一種反模式,事實上,如果應用程序除了發送一條單獨的消息之外還執行任何其他 JMS 工作。
最后,您可以考慮轉向ActiveMQ Artemis(即下一代 ActiveMQ),因為它支持“大”消息——這是 ActiveMQ 5.x 所缺乏的。
添加回答
舉報
0/150
提交
取消