ArrayList不会自动缩容,必须调用trimToSize()将elementData长度缩减至当前size;该方法安全高效,适用于批量删除后或确认不再大量添加的场景。

Java ArrayList 不会自动缩容,哪怕删掉 99% 的元素,底层数组(elementData)长度仍保持不变。内存吃紧时想真正释放闲置空间,必须手动干预。
调用 trimToSize() 是最简单有效的方式
这是 ArrayList 提供的唯一公共缩容方法,作用是将内部数组大小精确收缩到当前实际元素个数(size):
- 执行
list.trimToSize()后,list.elementData.length会等于list.size() - 底层调用
Arrays.copyOf(elementData, size),完成一次紧凑复制 - 无需反射、不破坏封装,安全且推荐在业务逻辑确认“后续不再大量添加”时使用
在批量删除后立即缩容效果更明显
像 removeAll()、retainAll() 或循环 remove() 后,size 显著变小但数组未变——此时调用 trimToSize() 能立刻回收大片内存:
- 例如:原数组容量 1000,删除后只剩 3 个元素 →
trimToSize()后数组变为长度为 3 的新数组 - 注意:
clear()只清空元素、重置size = 0,但elementData长度不变,仍需trimToSize()才能缩到 0
极端场景下可绕过 API 直接操作数组(慎用)
如果需要更精细控制(如只缩容但不触发其他副作用),可通过反射访问私有字段 elementData,再用 System.arraycopy 复制前 size 个元素到新数组并替换:
立即学习“Java免费学习笔记(深入)”;
- 适用场景极少,常见于高性能中间件或内存敏感的嵌入式 Java 环境
- 缺点:破坏封装、依赖 JDK 内部实现、可能在不同版本出错,一般项目不建议
- 普通业务开发中,
trimToSize()完全够用,也更稳定
缩容不是为了“看起来干净”,而是实打实地减少堆内存占用。尤其在长生命周期的缓存列表、批处理中间结果等场景,一次 trimToSize() 可能节省几 MB 甚至更多空间。


















