System.arraycopy是JVM内置的内存块搬运指令,仅在已分配数组间做地址级平移,不创建对象、不校验元素、不转换类型;其高效依赖迁移前的数据组织与约束控制,要求目标数组提前分配且容量精准,参数必须严格匹配,避免越界、类型错误及并发写入冲突。

System.arraycopy 不是通用拷贝工具,而是 JVM 内置的内存块搬运指令——它只在已分配数组间做地址级平移,不创建对象、不校验元素、不转换类型。真正高效迁移复杂数组数据,关键不在调用本身,而在迁移前的数据组织与约束控制。
目标数组必须提前分配且容量刚够
它从不扩容,也不容忍半点越界。迁移前务必确认:
- dest 数组已存在,且 dest.length ≥ destPos + length;少一个元素就抛 ArrayIndexOutOfBoundsException
- 避免在循环里 new 数组:高频分配会触发 Young GC,尤其当目标数组来自老年代时,可能引发跨代复制压力
- 推荐复用缓冲池(如固定大小 byte[8192]),用 arraycopy 覆盖写入,而非反复新建
精准控制起始位置与长度
所谓“迁移”,本质是把一段连续内存,按偏移写入另一段连续内存。参数错一位,结果就错一片:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 想取 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)
类型兼容性必须严格匹配
它不做隐式转换,也不绕过类型系统:
立即学习“Java免费学习笔记(深入)”;
- 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

















