从内存分配的角度来看,ArrayList 与 LinkedList

2022-09-01 05:43:00

我需要存储大量信息,例如java列表中的“名称”。项目的数量可以改变(或者简而言之,我无法预定义大小)。我认为,从内存分配的角度来看,LinkedList将是一个比ArrayList更好的选择,因为对于ArrayList,一旦达到最大大小,内存分配就会自动加倍,因此总是有可能分配比所需内存更多的内存。

我从这里的其他帖子中了解到,存储在LinkedList中的单个元素比ArrayList占用更多的空间,因为LinkedList还需要存储节点信息,但我仍然猜测我定义的场景LinkedList可能是一个更好的选择。另外,我不想进入性能方面(获取,删除等),因为已经对此进行了讨论。


答案 1

LinkedList可能会分配更少的条目,但这些条目比它们的成本要高得多 - 足以让即使是最坏的情况在内存方面也更便宜。ArrayListArrayList

(仅供参考,我认为你弄错了; 当它充满时增长1.5倍,而不是2倍。ArrayList

例如,请参阅 https://github.com/DimitrisAndreou/memory-measurer/blob/master/ElementCostInDataStructures.txt:每个元素消耗24个字节,而在最好的情况下,每个元素消耗4个字节,在最坏的情况下,每个元素消耗6个字节。(结果可能因 32 位与 64 位 JVM 以及压缩对象指针选项而异,但在这些比较中,成本至少为 36 字节/元素,充其量为 8,最差为 12。LinkedListArrayListLinkedListArrayList

更新:

我从这里的其他帖子中了解到,存储在LinkedList中的单个元素比ArrayList占用更多的空间,因为LinkedList还需要存储节点信息,但我仍然猜测我定义的场景LinkedList可能是一个更好的选择。另外,我不想进入性能方面(获取,删除等),因为已经对此进行了讨论。

需要明确的是,即使在最坏的情况下,也比具有相同元素的a小4倍。获胜的唯一可能方法是通过故意使用故意膨胀的值进行调用来故意修复比较,或者在添加值后从中删除大量值。ArrayListLinkedListLinkedListensureCapacityArrayList

总之,基本上不可能让赢的记忆比较,而如果你在乎空间,那么调用就会瞬间以巨大的优势再次夺冠。认真地。 获胜。LinkedListtrimToSize()ArrayListArrayListArrayList


答案 2

...但我仍然猜测我定义的场景LinkedList可能是一个更好的选择

您的猜测不正确。

一旦超过了数组列表的初始容量,支持的大小将介于条目数的 1 到 2 倍引用之间。这是由于用于增大后备阵列的策略。

对于链表,每个节点至少占用条目数的 3 倍,因为每个节点都有 一个 和 引用以及条目引用。(事实上,它是3倍以上,因为节点的对象标头和填充使用了空间。根据 JVM 和指针大小,它可以高达 6 倍。nextprev

链接列表使用的空间比数组列表少的唯一情况是严重高估了数组列表的初始容量。(对于非常小的列表...)


当您考虑它时,链接列表相对于数组列表的唯一真正优势是当您插入和删除元素时。即便如此,这取决于你如何做到这一点。