system.arraycopy 是 java 中唯一绕过 java 层循环与边界检查、直接触发 jvm 底层内存搬运的原语,不创建新数组,仅做地址级数据平移,适用于已有数组间同步,要求源目标数组非空且类型兼容,高频用于切片、平移、迁移等低 gc 压力场景。

System.arraycopy 是 Java 中唯一能绕过 Java 层循环与边界检查、直接触发 JVM 底层内存块搬运的原语。它不创建新数组,只做地址级数据平移,因此在高性能数据处理中不是“可选项”,而是关键基础设施。
适用于已有数组间的数据同步
它只搬运数据,不分配内存——这意味着源数组和目标数组都必须已存在且类型兼容:
- 目标数组(dest)长度必须 ≥ destPos + length,否则抛 ArrayIndexOutOfBoundsException
- 源数组不能为 null,否则抛 NullPointerException
- int[] → long[] 不允许;String[] → Object[] 允许;但 Object[] → String[] 运行时报 ArrayStoreException
高频实战场景:切片、平移、迁移
这些操作都不依赖新对象分配,全部复用已有缓冲区,显著降低 GC 压力:
-
切片提取:从 byte[] packet 中取 payload(如索引 12 起 1024 字节),写入预分配的 payloadBuf:
System.arraycopy(packet, 12, payloadBuf, 0, 1024) -
数组平移:实现左移一位(删除队首):
System.arraycopy(arr, 1, arr, 0, arr.length - 1),JVM 自动按重叠安全策略执行 - 缓存刷新:计算出新 int[] 结果后,批量覆盖旧缓存数组,避免引用替换带来的可见性问题
配合分治策略优化批量分发
在事件总线、消息分发器等场景中,arraycopy 本身不实现逻辑,但能支撑高性能结构:
- 将处理器列表按 CPU 核数切分,用 arraycopy 快速复制子段到本地线程数组,消除跨段竞争
- 注册变更时生成 handler 数组快照,用 arraycopy 批量复制后原子更新引用,读端零阻塞
- 优先级队列内部调整(如插队、弹出)依赖其重叠拷贝能力,比循环赋值快 3 倍以上
性能关键约束与避坑点
它的高速是有前提的,脱离条件反而拖慢系统:
- 拷贝长度 ≤ 16 时,JNI 调用开销可能超过简单 for 循环,建议小数据走分支判断
- 多线程并发写同一 dest 数组区域会引发数据撕裂,必须外加同步或改用不可变+引用替换
- 不要用它替代 Arrays.copyOf——后者封装了 new + copy,而 arraycopy 只负责后半段
- length 是元素个数,不是字节数;srcPos 和 destPos 是起始索引,不是偏移地址











