2009-08-07 118 views
2

哪個Java阻塞隊列最適合多個生產者和單個或多個消費者場景?哪個Java阻塞隊列最適合多個生產者和單個或多個消費者場景?

我使用LinkedBlockingQueue進行測試,但我得到OutOfMemoryError異常。

我正試圖實現以下目標。

  1. 生產者創建一個對象&放入隊列中。
  2. 消費者從隊列中抓取數據&插入到數據庫中。將有400家生產商,我可以根據需要調整消費者。

讓我知道任何想法。

更新

監製:應該聽服務器插槽。它從套接字&讀取數據構造對象(Domain對象)並放入一個隊列中。

消費:乘坐從隊列&刀片(支持的Hiberante &連接池)對象爲DB

這是我的真實環境。進程應該能夠處理至少200個記錄/秒。我正在測試過程的可伸縮性以及如何改進過程。我希望這會給出更好的想法。

幫助鏈接:

vmoptions

Monitoring and Managing Java SE 6 Platform Applications

BlockingQueue

回答

5

問題不在於你用哪Queue實現,而是如何對待你的節流生產者如果您消費者跟不上的問題。一種可能的解決方案是創建固定容量的LinkedBlockingQueue,並讓您的生產者撥打offer(E e),如果隊列已滿,將返回false

另一個可能的解決方案是根據生產者和消費者的數量來定製。

+2

+1我同意你的隊列似乎沒有明智的容量 - 默認是相當大的Integer.MAX_VALUE。如果您已將容量設置爲合理且仍然存在問題,請檢查您的Java堆設置-Xmx等...... – pjp 2009-08-07 09:48:51

+0

感謝球員們,我無法實時減少生產者大小,因此我必須處理它。如果我使用這個提議,我會失去那個對象,不是嗎?我正在使用put()和take()。這將根據隊列狀態等待。我在eclipse運行配置中將-vmargs配置爲-Xms512m -Xmx1024m。 – nayakam 2009-08-10 09:36:31

2

是每個生產者一個單獨的線程?不要忘記,每個線程將爲其堆棧分配(默認情況下)512k的內存(在您的情況下,需要爲線程提供200Mb的VM內存)。你可以通過-Xss減少這個。

或者,您排隊的對象有多大?我認爲你的隊列問題不是某種縮放問題 - 例如生產者生產速度快於消費者可消費。

+0

感謝您的輸入。我檢查了它在80k到90k之間增加的隊列大小增長並開始拋出OutOfMemoryError錯誤。隊列保持java類,它是包含10個字段的表的域類。 – nayakam 2009-08-10 01:33:21

+0

如果您的域對象的大小是500字節,那麼您的隊列將消耗.5kb * 90e3 = 45Mb。事實並非如此。所以我會再看看你的VM內存,也許a)增加虛擬機的大小,b)減少線程堆棧的大小。上面是被告知的猜測,順便說一句,不知道你的域對象有多大,或者你的應用程序做了多少。 – 2009-08-10 08:10:43

+0

感謝您的關注。我將VM大小增加爲-vmargs,爲-Xms512m -Xmx1024m。我爲生產者(400)和消費者(10)配置了睡眠時間1000毫秒。現在進程可以處理400條記錄/秒 – nayakam 2009-08-10 23:58:55

1

看來LinkedBlockingQueue是您的問題的最佳選擇。我建議你使用開關-XX:+ HeapDumpOnOutOfMemoryError運行你的程序,並分析轉儲文件以查看導致問題的原因。那麼你就可以更容易地解決它。

+0

謝謝,我無法獲得轉儲文件,我將-XX:+ HeapDumpOnOutOfMemoryError設置爲編程參數,REF鏈接[http://java.sun.com/javase/6/ webnotes/trouble/TSG-VM/html/clopts.html] – nayakam 2009-08-10 01:21:42

+0

嘗試搜索* .hprof文件的磁盤 – 2009-08-10 08:04:51

+0

是的,我沒有正確傳遞JVM選項。現在我得到了這個文件,但是當我嘗試用jhat實用程序執行時,它會拋出異常。 – nayakam 2009-08-11 03:40:50

相關問題