Java 有很多空对象会消耗内存吗?如果是的话,有没有替代使用ArrayQue作为队列的方法?

Java 有很多空对象会消耗内存吗?如果是的话,有没有替代使用ArrayQue作为队列的方法?,java,memory,queue,Java,Memory,Queue,我是一个n00b,所以我很抱歉,如果我与这一个,但我使用ArrayQue作为一些线程处理的队列。每个线程处理队列中某个项目的数据(每个线程检查队列中是否有数据,以及是否有数据。如果数据是queue.poll(),则将其发送到解决方案队列中,否则将丢弃该数据或将其一部分发送回队列进行进一步处理 这是我的问题,我的程序运行的时间越长,它使用的内存就越多,最终我从内存错误中解脱出来(但在这种情况发生之前,它会在一段时间内保持最大值)。我正在学习java,所以我不确定我是否正确识别了这一点,但我在代码上

我是一个n00b,所以我很抱歉,如果我与这一个,但我使用ArrayQue作为一些线程处理的队列。每个线程处理队列中某个项目的数据(每个线程检查队列中是否有数据,以及是否有数据。如果数据是queue.poll(),则将其发送到解决方案队列中,否则将丢弃该数据或将其一部分发送回队列进行进一步处理

这是我的问题,我的程序运行的时间越长,它使用的内存就越多,最终我从内存错误中解脱出来(但在这种情况发生之前,它会在一段时间内保持最大值)。我正在学习java,所以我不确定我是否正确识别了这一点,但我在代码上运行了yourkit,它说:

Find arrays with big number of 'null' elements.
Problem: Possible memory waste.
Possible solution: Use alternate data structures e.g. maps or rework algorithms.
yourkit还向我展示了我93%的内存被困在这里(堆转储中)。昨天我问了一个关于arraydeque.polling()可能占用内存的问题,并得到一条评论说这不是因为我的数据一旦被轮询就会变成“null”

因此,我的两个问题(如在我的标题中)是,空对象的数量不断增加。这是一个问题(我不确定它们是否得到GC’ed,但由于堆转储中有数百万个,我怀疑可能没有)?如果是,是否有替代ArrayQue的方法,可能是GC的项不再需要时使用的方法(我的程序不断地在队列中处理和添加项目,但即使要处理的项目数量减少了,内存消耗也不会下降,当程序完成时,内存消耗只是突然变为零,如果队列逐渐增加,我希望它会逐渐变小)


另一个稍微相关的问题是,我正在处理线程正在处理的队列中的数十亿项,但内存导致它失败。我是否有必要尝试改进我的内部程序队列,或者使用像(rabbitmq或activemq)这样的真正队列程序?(我对编程非常陌生,所以不确定什么时候我达到了工具的极限,以及如何改进它或找出下一步使用什么)

看起来
ArrayDeque
实现从未收缩其内部数组,因此它一直在增长。当从deque轮询对象时,其对应的数组元素设置为
null
,并且该对象最终将被垃圾收集(如果对它的所有其他引用也消失).但是
ArrayDeque
中的内部数组一直在增长


Deque
接口也是由
LinkedList
ConcurrentLinkedque
实现的,因此您最好使用其中的一个。

ArrayDeque
借助两个“指针”将项目存储在平面数组中-头和尾。如果队列中的元素总数超过此数组的当前大小,则其大小将加倍

从队列轮询项目时,此数组中的插槽将被清除(设置为
null
),但数组从未真正缩小!这意味着,如果您首先向队列提供一百万个项目,然后轮询所有项目,则
ArrayDeque
仍会维护一个至少包含一百万个项目的数组,所有项目都设置为
null
。这解释了查找包含大量“null”元素的数组的消息

似乎您的应用程序在某个时间点向队列提供了大量元素。请尝试(定期)调用以下代码:

queue = new ArrayDeque<String>(queue);
queue=newarraydeque(队列);
这将复制旧的
队列
的内容,垃圾收集不必要的大内部数组

请注意,没有空对象这样的东西-如果您从队列中删除了一个项目,并且代码不再引用该项目-它将被垃圾收集