system.arraycopy 的 jit 优化是将其替换为 cpu 原生指令,跳过字节码与边界检查;作为 intrinsic 方法,由 c2 编译器直接生成机器码,具备一次性校验、零分支搬运、硬件适配等特性。

System.arraycopy 的 JIT 优化不是“加速一个 Java 方法”,而是直接抹掉这个方法——HotSpot C2 编译器在热代码编译阶段,把它替换成 CPU 原生指令,跳过全部字节码、栈帧和 Java 层边界检查。
它被当作 intrinsic 处理,而非普通 native 调用
System.arraycopy 在 HotSpot 中被标记为 intrinsic 方法,这意味着:
- JVM 不会真的走 JNI 进入 C++ 层再调用 memmove;而是在编译时查表,直接生成等价机器码
- 是否生效取决于运行时条件:-XX:+UseIntrinsics(默认开启)、C2 编译器启用(TieredStopAtLevel > 1)、CPU 支持对应指令集(如 AVX、SVE)
- @IntrinsicCandidate 注解只是提示 JVM “这个方法可被内建”,不保证一定触发;真正决定权在 JIT 编译器的优化策略
一次校验 + 零分支内存搬运
手写 for 循环每轮都要做数组边界检查、变量读取、比较、跳转;而 arraycopy 的优化核心在于:
- 入口处一次性完成所有合法性验证:源/目标非空、索引合法、长度非负且不越界
- 后续全是裸指针顺序访存,无分支、无异常路径、无额外内存屏障
- 对齐地址下自动启用宽向量指令:x86-64 可能生成 rep movsq 或 AVX-512 vmovdqu64;AArch64 常用 ldp/stp 或 SVE ld1/st1
硬件级适配:预取、对齐与缓存友好
JIT 生成的拷贝代码会主动匹配现代 CPU 的内存子系统特性:
- 按 cache line(通常 64 字节)对齐搬运,减少 cache miss
- 自动插入 prefetch 指令,提前加载后续数据到 L1/L2 缓存
- 连续地址流式访问,完美触发 CPU 的 streaming prefetcher
- 小长度(
触发优化的关键实践
想让 arraycopy 真正跑出硬件级性能,需满足几个现实约束:
- length 尽量是编译期常量(如 1024),或稳定变量(避免频繁变化导致去优化)
- 数组类型明确:int[] → int[]、byte[] → byte[] 最优;泛型擦除后桥接调用(如工具类泛型 copy)会破坏内联
- 避免小数组滥用:单次拷贝
- 对象数组只拷引用,不触发 GC 或类型检查;但 Object[] → String[] 会在运行时报 ArrayStoreException











