System.arraycopy 提速关键在于跳过 Java 层循环和检查,直接调用 JVM 底层指令;但仅在数组足够大(如基本类型≥256)、类型匹配、目标已预分配时才更快,小数组或参数错误反而更慢。

System.arraycopy 能提速,关键在于它跳过 Java 层循环和逐元素检查,直接调用 JVM 底层内存搬运指令。但提速不是无条件的——小数组、类型不匹配、目标未预分配,反而更慢。
什么时候真正快:看数据量和类型
它快的前提是数组足够大、类型干净:
- 基本类型数组(int[]、byte[] 等)拷贝长度超过 256 时,优势明显;JVM 可启用 SIMD 指令批量搬动
- 对象数组(String[]、MyBean[])也快,但只复制引用,不触发 GC 写屏障,适合高吞吐场景
- 长度 ≤ 16 的数组,for 循环常更快——JNI 调用开销盖过了搬运收益
- 避免在循环体内频繁调用 arraycopy;参数尽量用编译期可判定的常量,利于 JIT 内联
原地移位重排:靠参数控制方向,不靠手写逻辑
同一数组内移动数据(如删除元素后前移、RingBuffer 左移),不用 for 循环,靠 src == dest + 参数顺序自动保安全:
- 左移(destPos < srcPos):System.arraycopy(arr, 4, arr, 2, 5) → JVM 正向执行,不会覆盖
- 右移(destPos > srcPos):System.arraycopy(arr, 2, arr, 5, 5) → JVM 自动倒序搬运,防止数据丢失
- 重叠区间合法且安全,但必须确保 srcPos + length ≤ arr.length 且 destPos + length ≤ arr.length
- 别手动判断方向再分支——传对参数,JVM 自己选策略
避坑要点:参数错一个,立刻抛异常
它不宽容,所有校验都在运行时一次性做,错就崩,不静默:
立即学习“Java免费学习笔记(深入)”;
- src 或 dest 为 null → NullPointerException
- srcPos、destPos 或 length 为负 → NegativeArraySizeException 或 IndexOutOfBoundsException
- srcPos + length > src.length 或 destPos + length > dest.length → ArrayIndexOutOfBoundsException
- int[] 拷到 long[]、String[] 拷到 Integer[] → ArrayStoreException(运行时,非编译时报错)
- length = 0 合法,可用于边界预检,不耗性能
比 Arrays.copyOf 和 clone() 更省的场景
当目标数组已存在、长度已知、只需搬数据时,arraycopy 是唯一零分配选择:
- Arrays.copyOf(src, len) 会 new 新数组,多一次堆分配和 GC 压力
- clone() 只能整数组复制,不能指定范围,也不能复用已有数组
- 正确做法:提前分配好 dst 数组,再 System.arraycopy(src, off, dst, 0, len)
- 网络缓冲区复用、ArrayList 扩容、日志环形队列清理头部冗余——都靠它省掉分配开销


















