System.arraycopy是JVM内置的高效内存块搬运指令,仅在已分配数组间做地址级平移,要求目标数组预先分配、边界精准、类型严格匹配,且需规避并发写入与动态分配。

System.arraycopy 不是“迁移函数”,而是 JVM 内置的内存块搬运指令——它不创建新数组、不校验元素、不处理类型转换,只在已有数组间做地址级平移。真正快的关键,是你提前把容器准备好、位置算清楚、干扰全排除。
目标数组必须提前分配且容量刚够
它从不扩容,也不容忍半点越界。迁移前务必确认:
- dest 数组已存在,且 dest.length ≥ destPos + length;少一个元素就抛 ArrayIndexOutOfBoundsException
- 不要在循环里 new 数组:高频分配会触发 Young GC,尤其当目标数组来自老年代时,可能引发跨代复制压力
- 推荐复用缓冲池(如固定大小 byte[8192]),用 arraycopy 覆盖写入,而非反复新建
精准控制起始位置与长度
所谓“迁移”,本质是把一段连续内存,按偏移写入另一段连续内存。参数错一位,结果就错一片:
- 想取 src 从索引 12 开始的 1024 字节?写 System.arraycopy(src, 12, dst, 0, 1024),不是 13,也不是 1025
- 要左移 RingBuffer 中未读数据?System.arraycopy(buf, readPos, buf, 0, unreadCount),JVM 自动正向搬运,不怕重叠
- length 尽量用常量(如 1024):JIT 更易内联、向量化,甚至启用 SIMD 指令;运行时变量建议加阈值判断(≥256 才走 arraycopy)
类型兼容性必须严格匹配
它不做隐式转换,也不绕过类型系统:
- int[] → int[]、String[] → Object[] 合法;但 int[] → Integer[] 或 byte[] → int[] 直接抛 ArrayStoreException
- 避免泛型中转(如 Arrays.asList().toArray()):类型擦除后破坏 JIT 内联,性能降级为普通循环
- 基本类型数组(byte[]、int[])最快:无 GC write barrier,JVM 可直发底层 memcpy/memmove
多线程写同一目标数组必须隔离
单次调用原子,但不线程安全:
- 多个线程往同一 dest 数组不同区域写(如 [0,999] 和 [1000,1999]),仍可能因 CPU 缓存未同步导致数据撕裂
- 正确做法:各线程操作独立 buffer,最后用一次 arraycopy 合并;或采用“新数组 + AtomicReference.lazySet”替换引用
- 切勿在无锁场景下并发调用 arraycopy 到同一个 dest

















