system.arraycopy高效运行的关键是严格满足jvm底层执行约束:目标数组须预分配且容量充足;源目标类型必须严格兼容;长度建议≥256并优先使用基本类型;原地复制时方向由srcpos与destpos自动判定。

System.arraycopy 不管理内存分配,它只做内存搬运——不申请新空间、不触发 GC、不构造对象。真正影响效率的,是开发者对它的调用方式是否贴合 JVM 底层执行路径。
目标数组必须提前配足容量
它不做扩容,也不检查目标数组是否够用,只按你给的地址和长度硬搬。一旦 destPos + length 超出 dest.length,立刻抛 ArrayIndexOutOfBoundsException。
- 复制前务必确保:dest 数组已创建,且长度 ≥ destPos + length
- 避免用 Arrays.copyOf() 封装后再手动调整——多一次堆分配,纯属冗余
- 若需动态长度,优先用 new int[n] 预分配,而非依赖扩容逻辑
类型匹配要严格到运行时
编译期只做引用兼容性检查,实际搬运时才校验元素类型。跨基本类型(int[] → long[])或逆向协变(Object[] → String[])都会在运行时报 ArrayStoreException。
- 同类型数组(int[] → int[]、String[] → String[])性能最优,走纯位拷贝路径
- 子类数组可拷到父类数组(如 ArrayList[] → List[]),但目标数组运行时类型必须能容纳源元素
- 泛型擦除后调用(如 T[] → Object[])会引入桥接方法,破坏 JIT 内联,应避免
大小阈值决定是否启用高效路径
小数组反而拖慢:length ≤ 16 时,JNI 调用开销常高于简单赋值;256 是更稳妥的启用分界点。
- length 尽量用编译期常量(如 1024),JIT 更易向量化或展开为 SIMD 指令
- 若 length 来自变量(如 packet.length),建议加分支判断:小包走 for,大包走 arraycopy
- 基本类型数组(byte[]、int[])比对象数组更快——后者拷的是引用,虽快但属浅拷贝
原地复制时方向由参数自动保障
当 src == dest,JVM 按 memmove 语义处理重叠区间:destPos > srcPos(右移)自动倒序搬;destPos
- 例如 System.arraycopy(arr, 2, arr, 5, 4) 安全右移,JVM 内部从高索引开始写
- System.arraycopy(arr, 4, arr, 1, 4) 安全左移,正向搬运不丢失数据
- 别自行判断“要不要倒序”——传参正确,JVM 自会选对策略











