system.arraycopy 快是因为 jvm 将其作为原子语义指令优化:一次性校验后直接内存块搬运,跳过字节码循环开销;jit 深度内建,支持 simd、预取、写屏障优化;内存访问顺序贴合硬件,避免伪共享,重叠拷贝自动适配,长数组性能跃升显著。

System.arraycopy 快,不是因为它“写了 C 代码”,而是 JVM 把它当作一个原子语义指令来对待——参数校验只做一次,之后直接走内存块搬运路径,完全跳过 Java 字节码循环的重复开销。
绕开运行时重复约束
手动 for 循环每次读写都要执行:
- 源数组索引检查:确认 srcPos + i
- 目标数组索引检查:确认 destPos + i
- 引用类型还要做 null 检查和运行时类型兼容验证(比如往 String[] 里塞 Integer 就会失败)
- JVM 还得解释或编译循环结构本身:跳转、条件判断、栈帧维护
而 System.arraycopy 在进入 native 前一次性完成全部合法性校验(空数组、索引范围、长度非负、类型可赋值),之后直接调用类似 memmove 的底层函数,整块内存顺序搬运,中间不经过任何 Java 字节码。
JIT 给它开了专属通道
HotSpot 对 System.arraycopy 做了深度内建优化,和普通方法待遇完全不同:
- 自动内联为紧凑汇编序列,甚至省略函数调用开销
- 识别连续内存区域后启用 SIMD 指令(x86 上可能用 movdqu 一次搬 16 字节,AVX-512 下可达 64 字节)
- 插入硬件预取指令,提升 L1 缓存命中率
- 配合 GC 卡表更新策略,减少写屏障触发频次(尤其在老年代拷贝时)
相比之下,for 循环是通用模式,JIT 难以确定是否可向量化或安全内联,优化空间有限。
内存访问更贴合硬件特性
for 循环中每次 aaload + aastore 构成两次离散访存,容易造成 cache line 反复加载与驱逐;System.arraycopy 则按页对齐、流式顺序读写,完美匹配 CPU 多级缓存预取机制。
- 基础类型数组(如 byte[]、int[])常逼近硬件 memcpy 极限带宽
- 避免伪共享(false sharing)风险
- 支持重叠拷贝(同数组内移位),JVM 自动选择前向或后向策略,语义等价于 memmove
实际性能分水岭
优势不是线性增长,而是随数组长度跃升:
- 长度
- 长度 20–1000:arraycopy 开始稳定胜出,且优势加速扩大
- 长度 > 10⁵:实测快 3–5 倍,在吞吐密集型服务中,毫秒差异可转化为可观 QPS 提升
它不创建新对象,不触发额外 GC,对长周期流处理(音视频、IoT 数据)尤为关键。











