ArrayList内存占用远小于LinkedList。ArrayList仅需数组存储引用(约12MB),而LinkedList每个Node约40字节,100万个元素达40MB,容器结构多占28MB;少量元素时差异不明显因ArrayList初始容量为10。

看每个元素实际占多少字节
内存占用不能只看“存了几个数”,得拆开看 JVM 里每个对象的结构。ArrayList 的 elementData 是一个连续的 Object[] 数组,里面存的是引用(64 位 JVM 下通常为 8 字节),而 LinkedList 每个元素都包装成一个 Node 对象:含一个数据字段(如 Integer 占 16 字节)、两个引用字段(prev 和 next,各 8 字节),再加上对象头(12 字节)和对齐填充(通常补到 8 字节倍数)。实测一个 Node<Integer> 在 HotSpot 上普遍占 40 字节左右。
对比 100 万个 Integer 的真实内存开销
假设你用 new ArrayList<>() 和 new LinkedList<>() 各存 1_000_000 个 Integer:
-
ArrayList:数组本身约 1_000_000 × 8(引用) = 8 MB,加上扩容预留(默认初始 10,最终容量约 1_500_000),总数组空间 ≈ 12 MB;Integer对象另算(每个 16 字节,共 16 MB),但这是共享开销,不因 List 实现而异 -
LinkedList:1_000_000 个Node× ~40 字节 = 40 MB,不含额外数组,也不预留空间
也就是说,仅容器结构本身,LinkedList 比 ArrayList 多占约 28 MB —— 这还没算链表遍历时更差的缓存命中率带来的间接成本。
为什么「少量元素」时差异反而不明显
当只存 1–10 个元素时,ArrayList 默认初始容量是 10,elementData 数组已分配 10 个引用槽(80 字节),而 LinkedList 虽然每个 Node 开销大,但数量少。此时两者内存差距可能只有几 KB,容易误判“差不多”。但只要元素量上到千级,链表的线性增长开销就迅速拉开差距。
别忽略 JVM 参数和对象对齐的影响
真实字节数会随 JVM 版本、是否开启指针压缩(-XX:+UseCompressedOops)、堆布局等变化:
- 开启压缩指针时,引用从 8 字节 → 4 字节,
Node可能从 40 字节 → 32 字节 -
ArrayList的数组本身不受压缩指针影响,但数组内引用字段受其影响 - JVM 会对对象做 8 字节对齐,所以哪怕你只加一个
int字段,也可能多占 4 字节填充
想精确测量,得用 java.lang.instrument.Instrumentation.getObjectSize() 或 JOL(Java Object Layout)工具,直接读运行时对象大小,而不是靠理论估算。

















