2013-04-06 62 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

相关问题