System.arraycopy()是Java中唯一能绕过Java层循环和边界检查、直接触发JVM底层内存块搬运的原语,不创建新数组,仅做地址级数据平移,具备单次调用的执行原子性,但不保证线程安全。
system.arraycopy() 是 java 中唯一能绕过 java 层循环和边界检查、直接触发 jvm 底层内存块搬运的原语,它不创建新数组,只做地址级数据平移,天然具备单次调用的执行原子性——即整个拷贝过程要么全部完成,要么抛异常中断,中间状态对外不可见。
内存块迁移的本质是地址指令直通它在 HotSpot JVM 中最终映射为memmove或优化后的 SIMD 指令(如 AVX),不是逐元素赋值,而是将一段连续内存按块读取、对齐搬运。这意味着:拷贝速度与数组长度几乎线性无关,而与 CPU 缓存行、内存带宽强相关基本类型数组(如 byte[]、int[])走纯字节路径,无 GC write barrier 开销对象数组仅复制引用值,不触发 finalize / clone / 构造,也不校验对象内容当 src == dest 且区间重叠时,JVM 自动选择前向或后向搬运策略,保证结果正确(例如左移一位:arraycopy(arr, 1, arr, 0, len-1))
原子性不等于线程安全单次 arraycopy 调用本身是原子操作,但“原子性”仅指该方法内部执行不可分割,并不提供跨线程保护:若多个线程同时对同一 dest 数组调用 arraycopy,且写入区域有交集,会出现数据撕裂(部分位置被覆盖、部分保留旧值)
没有内置锁或 CAS 机制,不参与 Java 内存模型(JMM)的 happens-before 保证若需多线程协同迁移,必须外加同步(如 synchronized 块、ReentrantLock),或采用不可变目标数组 + 引用替换方式真正发挥高性能迁移的关键约束性能优势只在满足以下条件时稳定释放:目标数组必须已存在且容量充足:dest.length ≥ destPos + length,否则抛 ArrayIndexOutOfBoundsException类型严格兼容:int[] 不能拷到 long[];String[] 可拷到 Object[],反之则 ArrayStoreException避免小数据量滥用:长度 ≤ 16 时,JNI 调用开销可能超过简单 for 循环;应结合实测阈值决策参数全为编译期可推导常量更易触发 JIT 内联优化:如 length 写死为 1024 比变量 int n 更利于生成最优汇编典型迁移场景与写法示意
常见高性能迁移模式包括:
缓存刷新:用新计算出的 int[] 替换旧缓存数组,通过 arraycopy 批量写入已分配缓冲区RingBuffer 移位:byte[] 实现的网络包缓冲区,接收新数据后用 arraycopy 整体前移腾出空间ArrayList 删除收缩:remove(int i) 触发 arraycopy(elementData, i+1, elementData, i, size−i−1),高效前移后续元素零拷贝封装:配合 ByteArrayInputStream 或 DirectByteBuffer 使用,避免额外内存分配和复制
