system.arraycopy 提升性能的核心是“不复制新内存”,它绕过 java 层直调底层 memmove,实现已有缓冲区内原地流转,消除 gc 压力、避免引用可见性问题,并支持重叠安全搬运。

System.arraycopy 在缓冲区处理中提升性能,核心不是“复制更快”,而是“不复制新内存”——它绕过 Java 层、直连底层 memmove,让数据在已有缓冲区内原地流转,从而消除 GC 压力、避免引用替换可见性问题,并支持重叠安全搬运。
复用缓冲区,实现零分配搬运
网络通信、音视频解码、日志采集等场景中,频繁 new byte[] 是 GC 主要压力源。arraycopy 不创建对象,只把新数据写入已分配的 buffer 中指定位置:
- 预分配一个大缓冲池(如
byte[] pool = new byte[1024 * 1024]),按 slot 划分,用 arraycopy 将收到的 packet 写入对应 offset - 消费时,不复制整块,而是用
System.arraycopy(packet, headerLen, payloadBuf, 0, payloadLen)提取有效载荷到业务小数组 - 环形缓冲区滚动时,靠两次 arraycopy 拼接跨尾部+头部的数据段,比手写循环更安全且易被 JIT 向量化
精准控制内存落点,触发硬件级优化
arraycopy 本身不优化布局,但能让你把数据“摆”到利于 CPU 访问的位置:
- byte[] 建议按 16 字节对齐分配:
new byte[(size + 15) & ~15],再从 offset=0 或 16 的倍数开始拷贝,更容易激活 AVX/SIMD 指令 - 避免小块跨 cache line:单次拷贝长度
- length 尽量用编译期常量(如 1024),JIT 更可能内联并展开为高效指令;运行时长度建议加分支:
if (len
原地重排,替代手动循环移位
在 RingBuffer、ArrayList 删除首元素、协议包头剥离等场景,不需要新建数组,只需物理位移:
- 左移一位(消费队首):
System.arraycopy(arr, 1, arr, 0, arr.length - 1),JVM 自动正向执行,安全覆盖 - 右移一段(插队或扩容后迁移):
System.arraycopy(arr, 0, arr, 3, 5),JVM 自动倒序搬运,防止中间值丢失 - 禁止
srcPos == destPos && length > 0的无效调用——虽合法,但白耗一次边界校验开销
保证缓存一致性与读端快照
多线程下直接替换数组引用(如 cache = newData)存在可见性风险;而用 arraycopy 覆盖旧数组内容,可让读线程看到一致快照:
- 计算出新 int[] 结果后,用
System.arraycopy(newData, 0, cacheArray, 0, newData.length)批量刷新,避免引用变更导致的指令重排序问题 - 多线程写同一 dest 数组不同区域仍可能因缓存未同步出错,推荐各线程操作独立 buffer,最后用一次 arraycopy 合并
- 若需原子更新,可用新数组 +
AtomicReference.lazySet替换引用,读端无锁访问
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











