System.arraycopy 能提速,关键在于绕开 Java 字节码执行路径,由 JVM 内核直接调度硬件级内存搬运指令:一次性参数校验后调用本地函数,JIT 内联生成向量化机器码,支持 prefetch 与页对齐批量读写,并自动处理重叠拷贝方向。

System.arraycopy 能提速,关键不是“调用它就快”,而是它绕开了 Java 字节码执行路径,直接交由 JVM 内核调度硬件级内存搬运指令——不是优化循环,是根本不用循环。
跳过 Java 层重复校验
手动 for 循环每次迭代都要查四件事:源数组长度、源索引是否越界、目标数组长度、目标索引是否越界;引用类型还得加 null 检查和类型校验。这些是字节码固定开销,无法消除。
System.arraycopy 只在入口一次性做完全部参数检查(src/dest 非空、索引合法、length ≥ 0、类型兼容),之后直接调用类似 memmove 的本地函数,不经过任何 Java 栈帧或解释器。
JIT 编译器深度内联生成硬件指令
HotSpot C2 编译器把 System.arraycopy 视为 intrinsic 方法,热代码中会完全内联为紧凑机器码:
立即学习“Java免费学习笔记(深入)”;
- 地址对齐 + 大长度时,自动生成 rep movsq(x86) 或 ldp/stp 成对加载存储(ARM)
- 支持 AVX/SSE 或 SVE 向量指令,一次搬运 16–64 字节,无需手动循环展开
- 自动插入 prefetch 指令,提升 L1/L2 缓存命中率
- 连续顺序读写,匹配 CPU 预取机制,避免伪共享和 cache line 反复驱逐
内存访问模式高度友好
for 循环中每次 aaload + aastore 是两个离散访存动作,容易导致 cache line 反复加载;而 arraycopy 是流式、页对齐、批量读写:
- 基本类型数组(如 byte[]、int[])拷贝常逼近 memcpy 硬件带宽极限
- 对象数组只拷引用,不触发 write barrier(年轻代内拷贝时)
- G1/ZGC 下可配合卡表策略做细粒度并发调度
重叠拷贝自动选方向,语义等价 memmove
当 src == dest 时(如 RingBuffer 数据前移),arraycopy 不依赖用户判断方向,而是根据 srcPos 与 destPos 大小关系自动选择正向或倒序搬运:
- destPos > srcPos(右移)→ 倒序复制,防止未读数据被覆盖
- destPos ,保持数据完整性
- 语义与 C 的 memmove 一致,不是 memcpy


















