system.arraycopy在字节数组操作中承担内存级搬运角色,精确移动已读取字节,不解析内容、不扩容、不新建对象,支持安全重叠拷贝,实测≥256字节时比for循环快2–5倍。

System.arraycopy 在字节数组操作中,是真正承担“内存级搬运”的底层支柱——它不解析内容、不封装逻辑,只做精确、可控、零额外开销的字节块移动。
它是字节流处理的“搬运扳手”,不是“智能管道”
在网络通信、音视频解码、序列化/反序列化等场景中,byte[] 是最常出现的原始载体。System.arraycopy 不参与协议解析或格式转换,而是负责把已读取的字节从一个缓冲区高效转移到另一个缓冲区:
- 从 SocketChannel 读出的固定大小接收缓冲区(如 byte[8192])中,提取有效 payload 段,搬入解码器专用输入 buffer
- 在 RingBuffer 实现中,消费完头部数据后,用它把剩余未处理字节前移到起始位置,腾出空间继续接收
- 将多个 UDP 包的 byte[] 片段,按顺序拼接到一个大 buffer 中,为后续帧组装做准备
参数必须严丝合缝,否则立刻失败
对 byte[] 来说,arraycopy 的健壮性来自它的“零容忍”设计:
- srcPos 和 destPos 是下标,不是字节偏移地址;length 是元素个数,不是字节数(byte[] 中二者数值相同,但语义不能混淆)
- 若 srcPos + length > src.length 或 destPos + length > dest.length,直接抛 ArrayIndexOutOfBoundsException —— 这是明确的边界信号,不是静默截断
- 目标数组必须预先分配且足够长;它不扩容、不新建,只搬运
重叠拷贝是它独有的安全能力
当 src 和 dest 是同一个 byte[] 时,arraycopy 能自动识别重叠区域并选择安全拷贝方向:
- 左移一位(删除首字节):System.arraycopy(buf, 1, buf, 0, remaining) → JVM 正向执行,无覆盖风险
- 右移 k 字节(预留头部):System.arraycopy(buf, 0, buf, k, len) → JVM 自动倒序搬运,避免中间数据被提前擦除
- 手动 for 循环做不到这点,容易因顺序错误导致数据损坏
性能优势在真实流负载中立竿见影
实测表明,在 ≥256 字节的搬运任务中,arraycopy 比等效 for 循环快 2–5 倍:
- 绕过每次 aaload/aastore 的边界检查和栈帧维护
- JVM 可将其内联为 memmove 级指令,甚至触发 SIMD 并行搬运
- 不创建对象,不触发写屏障,长期运行的服务 GC 压力显著降低











