System.arraycopy是JVM内存块搬运原语,不分配内存、不校验内容、不处理对象生命周期;高效迁移依赖结构预判、参数对齐与缓冲区复用,如网络收包中预分配byte[8192]并反复填充读取,同数组移位时靠srcPos/destPos自动选择方向,拼接需严格对齐destPos,且五参数必须全合法否则立即抛异常。

System.arraycopy 不是万能拷贝函数,而是 JVM 内存块搬运原语——它只负责把一段连续内存从 A 地址搬到 B 地址,不分配、不校验内容、不处理对象生命周期。真正决定“高效迁移”成败的,是结构预判、参数对齐与复用策略。
复用缓冲区:避免频繁分配是性能底线
高频场景(如网络收包、日志聚合、RingBuffer)中,数组迁移不是“复制一次就丢”,而是反复填充-读取-清理-再填充。此时必须提前分配固定大小的目标数组,并在每次迁移前复用它:
- 目标数组(如 byte[8192])应在初始化阶段一次性创建,后续所有 System.arraycopy 都指向它
- 迁移时只控制 srcPos 和 length,例如从 packet 中截取 payload:System.arraycopy(packet, headerLen, buffer, 0, payloadLen)
- 避免在循环内 new 数组——哪怕只是 int[1024],每秒千次分配也会触发 Minor GC,拖慢整体吞吐
处理重叠结构:同数组内移位必须靠参数驱动
当 src == dest,arraycopy 就变成原地重排工具。它不关心“你要做什么”,只根据 srcPos 与 destPos 的大小关系自动选择搬运方向,确保数据不丢失:
- 左移(destPos < srcPos):如删除 ArrayList 中第 i 个元素后,将 i+1 到末尾前挪:System.arraycopy(arr, i + 1, arr, i, size - i - 1)
- 右移(destPos > srcPos):如为插入腾空间,把 arr[i..n-1] 整体右移一位:System.arraycopy(arr, i, arr, i + 1, size - i)
- 无需手动倒序循环——JVM 已内置 memmove 语义,传对参数即可安全执行
拼接与截取:两段搬运需严格对齐偏移
数组拼接不是语法糖操作,而是两次独立的内存搬运。关键在于第二段的 destPos 必须等于第一段实际写入长度,否则覆盖或留空:
立即学习“Java免费学习笔记(深入)”;
- 拼接 a 和 b 到 result:System.arraycopy(a, 0, result, 0, a.length); System.arraycopy(b, 0, result, a.length, b.length)
- 截取 src 中 [offset, offset + len) 段到 dest:System.arraycopy(src, offset, dest, 0, len),前提是 offset + len ≤ src.length 且 dest.length ≥ len
- 常见错误:destPos 写成 0 或 b.length,导致数据错位;或未校验 offset 是否越界,运行时直接崩溃
类型与边界:五个参数一个都不能松动
arraycopy 的强约束不是设计缺陷,而是性能保障的前提。任何参数违规都会立即抛异常,没有容错余地:
- 非 null 校验:src 和 dest 任一为 null,抛 NullPointerException
- 索引合法性:srcPos ≥ 0、destPos ≥ 0、srcPos + length ≤ src.length、destPos + length ≤ dest.length,缺一即 ArrayIndexOutOfBoundsException
- 类型兼容性:int[] 只能拷到 int[];String[] 可拷到 Object[],但 Object[] 拷到 String[] 会在运行时遇到非 String 元素时报 ArrayStoreException


















