Java数组扩容原理网站logo 数组扩容原理·JAVA

Java数组扩容原理 · 数组扩容JAVA 深度拆解

内存分配数据迁移,从 ArrayList 到原生数组,彻底讲透 Java数组扩容原理。不只是理论,更有实战示例与网友最关心的周边热点。

⚙️ 核心扩容原理 · 暗度陈仓的内存艺术

重新分配 · 拷贝溢出

数组扩容本质是“重新分配+数据拷贝”。JVM 寻找更大的连续内存,将旧数据逐一迁移。扩容不是简单的“加大”,而是新瓶装旧酒。旧数组变成“死”数组,新数组成为工作区。

  • 同步扩容:线程内完成,保证数据一致
  • 溢出机制:旧数据末尾被“推”到新位置
  • GC 隔离:新旧数组内存独立,避免回收混乱
? 数据搬运 · 三步走

int[] arr = {1,2,3,4,5} 扩容到100为例:① 拷贝全部旧数据到临时数组 temp;② 将剩余未拷贝部分(溢出)填入后续位置;③ 替换引用,旧数组废弃。每一步都涉及内存连续性保障。

  • 第一步:完整拷贝副本
  • 第二步:溢出填充,利用连续内存
  • 第三步:引用替换,旧数组不可用
?️ 线程安全 · 绝对保险

扩容操作必须在绝对保险的线程内完成。任何并发读写都会导致数据错乱或异常。JDK 中 ArrayList 的扩容由 grow() 方法封装,外部调用无需关心内存细节,但内部同步块保证安全。

扩容时不可触发其他同步操作,避免死锁或状态不一致。

? 热点聚焦 · 网民最关心的扩容话题

? 扩容性能 · 为什么说扩容是“脏活累活”?

数组扩容涉及 O(n) 的数据拷贝,当元素数量巨大时,频繁扩容会严重拖慢响应。网友常问:“ArrayList 每次扩容多少?” 默认是 1.5 倍(旧容量 + 旧容量右移1位)。扩容次数越少,性能越好。建议预分配容量:new ArrayList<>(1000) 避免多次扩容。

  • 扩容因子:1.5 倍是时间与空间的权衡
  • 内存碎片:频繁扩容导致GC压力
  • 优化技巧:使用 ensureCapacity()Arrays.copyOf 手动控制
// ArrayList 扩容核心 (JDK 17)
private void grow(int minCapacity) {
  int oldCapacity = elementData.length;
  int newCapacity = oldCapacity + (oldCapacity >> 1); // 1.5倍
  elementData = Arrays.copyOf(elementData, newCapacity);
}

? ArrayList 扩容 vs 原生数组扩容

ArrayList 封装了动态扩容,底层仍是 Object[],扩容时调用 Arrays.copyOf()。而原生数组一旦创建长度固定,无法真正“扩容”,只能通过新数组+拷贝模拟。网友误区:“数组可以自动扩容吗?” 答案是否定的,所有“扩容”都是新数组的创建与引用替换。

  • ArrayList:自动扩容,默认10,1.5倍增长
  • 原生数组:手动扩容,int[] newArr = Arrays.copyOf(old, newLength);
  • LinkedList:无需扩容,但内存开销更大

网友关心:“扩容时原来的数据会丢失吗?” 不会,copyOf 保证完整迁移。

? 拷贝优化 · System.arraycopy 与 Arrays.copyOf

System.arraycopy 是 native 方法,内存拷贝极快;Arrays.copyOf 内部调用前者。网友常混淆:两者都是浅拷贝,但对于基本类型数组完全安全。扩容时推荐使用 Arrays.copyOf,简洁且不易错。

// 高效扩容示例
int[] original = {1,2,3,4,5};
int[] expanded = Arrays.copyOf(original, 10);
// expanded = [1,2,3,4,5,0,0,0,0,0]
  • System.arraycopy:可指定源位置,目标位置,长度
  • Arrays.copyOf:更高级,自动填充默认值
  • 注意:多维数组深拷贝需手动遍历

⏳ 数组扩容时间轴 · 从旧数组到新容器

触发扩容:当数组元素已满(如ArrayList add 操作),计算新容量(1.5倍或指定值)。

分配新内存:JVM 在堆中寻找连续内存块,大小为 newCapacity。

数据拷贝:使用 System.arraycopy 将旧数组所有元素拷贝到新数组。

溢出处理:若旧数组末尾有剩余元素(实际不存在),逻辑上“溢出”到新数组后续位置,但实际拷贝已完成全部元素。

引用替换:新数组赋值给原引用,旧数组失去引用,等待GC回收。

? 丰富示例 · 手写扩容与常见陷阱

? 手动模拟数组扩容
// 模拟 ArrayList 扩容逻辑
public static int[] resize(int[] oldArr, int newCapacity) {
  int[] newArr = new int[newCapacity];
  System.arraycopy(oldArr, 0, newArr, 0, Math.min(oldArr.length, newCapacity));
  return newArr;
}
// 使用:int[] bigger = resize(arr, 100);

注意:如果 newCapacity < oldArr.length,会截断数据,这是“缩容”。

⚠️ 常见陷阱 · 线程不安全

多线程环境下同时扩容会导致 数据丢失数组越界。网友常踩坑:使用 ArrayList 未加同步,多个线程 add 触发并发扩容,出现 ArrayIndexOutOfBoundsException。解决方案:使用 CopyOnWriteArrayList 或加锁。

  • 错误示范:多个线程直接调用 list.add()
  • 正确做法:使用 Collections.synchronizedList
? 扩容对比:ArrayList vs Vector

Vector 扩容翻倍(100%增长),ArrayList 增长50%。网友关心:“哪个更省内存?” ArrayList 更节省,但 Vector 线程安全(已过时)。实际开发中,ArrayList 配合显式 ensureCapacity 更优。

? 扩容原理深层剖析 · 为什么不能共享内存?

很多初学者疑惑:“扩容时为什么不直接让新旧数组共用内存?” 这源于 Java 的 GC 机制。如果两个数组引用同一块内存,一旦其中一个引用被回收,另一个将指向无效数据。此外,数据隔离 保证了扩容过程中并发操作的安全性。JVM 设计者选择“拷贝+替换”而非“共享”,是为了确定性行为,避免幽灵读。

另一个关键点:数组扩容是同步的,因为 JVM 需要保证在扩容瞬间,所有线程看到的是完整的新数组或旧数组,绝不会出现“中间状态”。这也是 volatile 关键字无法解决的,必须通过同步块或 final 域保证。

网友常问:“扩容时旧数组真的完全不可用了吗?” 是的,一旦新数组赋值给引用,旧数组就变成垃圾。但若有其他引用指向旧数组,则仍可访问,但数据是旧版本。因此,扩容后应确保所有引用更新。

// 错误示例:持有旧引用
int[] oldRef = arr;
arr = Arrays.copyOf(arr, 100);
// oldRef 仍指向旧数组 (长度5)

理解这些,才算真正掌握 Java数组扩容原理

◆ 最新
heat exchanger 工作原理-热交换器工作原理贴吧二维码防删图原理-二维码防删图原理airpods定位的原理-Airpods 定位核心原理液晶屏工作原理及维修-液晶屏原理维修太阳能水位探头工作原理-太阳能水位探头工作原理直升机推进原理-直升机推进原理马自达cx8四驱工作原理-马自达 CX8 四驱工作原理v锥流量计原理动画-v 锥流量计原理动画可控硅控制电加热原理-可控硅电加热原理汽车手刹原理和保养-汽车手刹原理与保养明矾净水的原理方程式-明矾净水原理方程式微波双平衡混频器原理-微波双平衡混频器原理光伏发电原理讲解视频-光伏发电原理讲解视频蜂窝活性炭的吸附原理-活性炭吸附原理九阳电磁炉原理图 下载-九阳电磁炉原理图真空感应熔炼炉原理-真空感应熔炼原理安卓操作系统原理-安卓系统工作原理污水提升器原理-污水提升器工作原理车胎自补液原理-轮胎自补原理低失真音频电路原理-低失真音频电路原理vr原理详解-VR 原理详解初级抗阻动作及原理-初级抗阻动作与原理天然气锅炉原理介绍-天然气锅炉工作原理飞梭旋钮原理动画演示-飞梭原理动画演示非开挖钻机工作原理-非开挖钻机工作原理5mt变速箱工作原理-5MT 变速箱工作原理自动温度控制器原理图-自动温控器原理图光伏发电原理自制方法-自制光伏发电原理橡胶磨损原理-橡胶磨损基本机制zookeeper原理解析-zk 原理深度解析药代动力学实验原理-药代动力学实验原理喉咙异物感是什么原理-异物感源于咽喉黏膜牵拉充电芯片原理-充电芯片工作原理水表的结构和工作原理-水表结构与工作原理垃圾清理船的工作原理-垃圾清理船工作原理换热芯体原理-换热芯体工作原理热熔胶喷胶机原理-热熔胶喷胶机工作原理超声波塑胶熔接机原理-超声波塑胶熔接机原理荧光探针的原理-荧光探针原理简介qpcr原理详解-qpcr 原理详解法老之蛇实验原理-法老蛇实验原理短路保护工作原理-短路保护工作原理解真空回流焊的工作原理-真空回流焊工作原理真石漆喷涂机原理-真石漆喷涂机工作原理M2210的原理图设计图像处理器的工作原理-图像处理器工作原理精油的作用原理是什么-精油作用原理解析快排阀原理图解-快排阀原理图解话费慢充原理-话费慢充原理详解离心式过滤器原理图-离心过滤器原理图灭蚊器是什么原理-灭蚊器工作原理洗涤沉淀操作原理-洗涤原理与沉淀方法法士特取力器原理-法士特取力器工作原理气垫船原理与设计-气垫船原理与设计电子秤原理电路图-电子秤原理电路图电动机的原理与维修-电动机原理与维修作用式调压器工作原理-作用式调压器原理尼瑞克戒烟贴原理-尼瑞克戒烟贴原理无边泳池原理-泳池原理无边3d风扇原理图-3D 风扇原理图电动三通阀工作原理图-电动三通阀工作原理图串激电动机工作原理-串激电机工作原理电容原理差压传感器-差压电容传感器原理农用潜水泵原理-农用潜水泵工作原理阴极保护防腐技术原理-阴极保护防腐原理试漏机工作原理图-试漏机原理图str鉴定的原理-STR 鉴定原理介绍灭蚊灯的原理及图解-灭蚊灯原理图解削片机原理图解-削片机原理图解磷灰石定年原理-磷灰石定年原理360隔离沙箱原理-360沙箱隔离原理pcp自动回膛原理图-自动回膛原理图159减肥原理-160 减肥原理汽车刹车系统工作原理-汽车刹车系统工作原理纤磁纤惠减肥原理-纤磁纤惠减重原理(10 字)校园饮水机原理-校园饮水工作原理连杆传动的原理-连杆传动原理简述管壳式换热器原理-管壳式换热原理铜线剥皮机原理-铜线剥皮原理解析空气炸锅原理和微波炉一样吗-空气炸锅原理与微波炉是否相同车牌识别系统原理图-车牌识别系统原理图二向色镜的原理-二向色镜工作原理matlab随机数原理-matlab 随机数原理简化儿童玩具陀螺仪原理-儿童玩具陀螺仪原理铜的辟邪原理-铜制辟邪原理自动控制原理胡寿松ppt-自动控制原理胡寿松 PPT石膏 铸造 原理-石膏铸造原理电动伸缩看台结构原理-电动伸缩看台原理卧螺式离心机工作原理-卧螺离心机工作原理开式冷却塔工作原理-开式冷却塔工作原理总磷在线监测原理-总磷在线监测原理铁丝调直原理-铁丝调直原理风杯式风速表原理-风杯测速仪原理stm32功能板的原理图-stm32 功能板原理图电磁锁原理讲解-电磁锁原理说明晕车药的成分作用原理-晕车药成分及原理镍钯金打线原理-镍钯金打线原理简述蜗卷弹簧机械原理图-蜗卷弹簧原理图冷水机组制冷原理动画-冷水机组原理动画
瑞秋资讯
蜀ICP备2026006976号-18