2013-04-06 57 views
1

我一直在使用LinkedBlockingQueue,並且最近由於插入性能低而將其更改爲ArrayBlockingQueue。那之後我獲得了顯着的性能提升。然而,我的代碼的某個時候拋出內存外的一個錯誤:使用Integer.MAX_VALUE條目創建ArrayBlockingQueue時發生OutOfmemory錯誤

我的Java代碼

ArrayBlockingQueue<String> s = new ArrayBlockingQueue<String>(Integer.MAX_VALUE); 

我看了ArrayBlockingQueue源代碼。真的,我感到震驚 - 它爲給定的初始容量分配object[]。這是內存不足錯誤的原因。

ArrayBlockingQueue源代碼

public ArrayBlockingQueue(int capacity, boolean fair) { 
    if (capacity <= 0) 
     throw new IllegalArgumentException(); 
    this.items = (E[]) new Object[capacity]; 
    lock = new ReentrantLock(fair); 
    notEmpty = lock.newCondition(); 
    notFull = lock.newCondition(); 
} 

這並不猜測初始容量或創建具有最小容量的隊列。因爲它在高峯時間和正常時間會有所不同。如果我給出最小容量,隊列將在高峯時間立即填充。如果我給出最大容量,則會出現內存不足錯誤,並且在插入元素之前我不想分配對象[]。

請提出任何替代方案。

+1

剛剛啓動更多內存的Java? '-Xmx 32G'或其他。另外,你還將如何創建一個通用的ArrayBlockingQueue? – Sanchit 2013-04-06 08:25:11

回答

5

刪除構造函數的參數。爲什麼你的隊列需要那麼多容量?一個合理的數量開始像10或100或1000

此行是荒謬的:

ArrayBlockingQueue<String> s = new ArrayBlockingQueue<String>(Integer.MAX_VALUE); 

你不需要的2147483647的初始容量這只是2GB的隊列!

+0

這是一個固定的容量。隊列將快速填充。 – kannanrbk 2013-04-06 08:25:16

+1

不支持2GB的條目。這個想法是添加一個足夠快速響應的消費者池,從而永遠不會填充隊列。如果它確實滿了,生產者將阻塞,直到房間被釋放。這就是隊列的工作原理。 – duffymo 2013-04-06 08:25:37

相關問題