System.arraycopy是JVM内存搬运指令的Java接口,非通用拷贝工具;其高效依赖预分配数组、精准边界计算与类型匹配,适用于大批量搬运、部分截取拼接及原地重排三类场景。

System.arraycopy 不是“通用拷贝工具”,而是 JVM 内存搬运指令的 Java 接口。它真正高效的前提,是你已经把数据组织好、位置算清楚、干扰全排除——迁移成败,不在调用那行代码,而在调用之前。
明确场景:什么情况下必须用 arraycopy
它适合三类典型迁移任务:
- 大批量整块搬运:比如 ArrayList 扩容时将旧数组全部搬入新数组,或缓存淘汰后批量刷盘
- 部分截取与拼接:网络包解析中跳过 header 取 payload;日志聚合时把多个 buffer 片段按序写入结果数组
- 原地重排腾空间:RingBuffer 中读指针前移后,把未处理数据整体左移到缓冲区起始;删除 List 中间元素后向前覆盖
参数校验:5个数字一个都不能错
调用前必须确保:
- src 和 dest 都非 null,且类型兼容(int[] → int[] 合法,int[] → Integer[] 直接抛 ArrayStoreException)
- srcPos ≥ 0,destPos ≥ 0
- srcPos + length ≤ src.length(否则 ArrayIndexOutOfBoundsException)
- destPos + length ≤ dest.length(同上)
- length ≥ 0(length == 0 合法,可用于边界预检)
建议封装成工具方法,用 Math.min 控制 length 上限,避免运行时崩溃。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
立即学习“Java免费学习笔记(深入)”;
性能关键:让 JVM 真正跑出 SIMD 速度
快不是默认状态,需主动配合:
- 基本类型优先:byte[]、int[]、long[] 拷贝最快,无 GC write barrier,JVM 可直发 AVX/SVE 指令
- 长度尽量用常量:如 1024、4096;变量 length 会削弱 JIT 内联和向量化机会
- 单次搬运 ≥ 64 字节:小块(如 ≤ 32 字节)可能不触发向量化,高频小拷贝建议合并或改用循环
- 缓冲区预对齐:byte[] 按 16 字节边界分配(new byte[(size + 15) & ~15]),再从 offset=0 或 16 的倍数开始写入,更易命中 SIMD 优化路径
复用与安全:避免 GC 压力和并发撕裂
真正拉开性能差距的操作在“不 new”里:
- 用固定大小缓冲池(如 byte[8192])代替频繁 new byte[],通过 arraycopy 覆盖写入,维持内存驻留
- 多线程写不同区域?确保各线程操作独立 buffer,最后用一次 arraycopy 合并;不要并发往同一 dest 数组不同偏移写
- 环形缓冲区跨尾部+头部搬出数据?拆成两次调用:先 copy 尾部,再 copy 头部,比手写循环更安全且易被 JIT 优化

















