【问题标题】:OutOfmemory error when creating ArrayBlockingQueue with Integer.MAX_VALUE entries使用 Integer.MAX_VALUE 条目创建 ArrayBlockingQueue 时出现内存不足错误
【发布时间】:2013-03-28 17:39:50
【问题描述】:

我一直在使用LinkedBlockingQueue,由于插入性能缓慢,最近将其更改为ArrayBlockingQueue。在那之后我得到了显着的性能提升。但是,我的代码有时会引发内存不足错误:

我的 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();
}

这不会猜测初始容量或创建具有最小容量的队列。因为高峰时间和正常时间会有所不同。如果我提供最小容量,队列将在高峰时段立即填满。如果我给出最大容量,则会出现内存不足错误,并且我不想在插入元素之前分配 object[]。

请提出任何替代方案。

【问题讨论】:

  • 只是用更多内存启动java? -Xmx 32G 或其他。另外,您还打算如何创建一个通用的 ArrayBlockingQueue?

标签: java performance memory-management collections capacity


【解决方案1】:

删除构造函数的参数。为什么您的队列需要这么多容量?从一个合理的数字开始,例如 10、100 或 1000。

这句话很可笑:

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

您不需要 2147483647 的初始容量。这只是队列的 2GB!

【讨论】:

  • 这是一个固定容量。队列将很快被填满。
  • 不是 2GB 条目,它不会。这个想法是添加一个消费者池,这些消费者池响应速度足够快,以至于队列永远不会被填满。如果它确实填满了,生产者将阻塞,直到空间被释放。这就是队列的工作原理。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-10
  • 1970-01-01
  • 1970-01-01
  • 2012-05-15
  • 2020-02-20
相关资源
最近更新 更多