避免内存拷贝的核心是复用 ArrayBuffer 并通过 TypedArray/DataView 切换视图解读,subarray() 零拷贝共享,slice() 独立复制;多视图可同时访问同一 buffer;transferable 机制跨线程转移所有权而非复制;TextEncoder/TextDecoder 和 base64 操作均隐含拷贝。

避免内存拷贝的关键不是“不复制”,而是让复制变得可选、可控、甚至彻底绕过——核心在于复用底层 ArrayBuffer,用视图(TypedArray / DataView)切换解读方式,而非搬运字节。
用 subarray() 和 slice() 区分语义
两者都返回新视图,但行为不同:
- subarray(start, end):返回共享同一 buffer 的新 TypedArray,零拷贝。适合提取数据段做局部处理,比如解析协议头、读取图像某一块像素。
- slice(start, end):返回独立副本,会分配新内存并复制字节。仅在确实需要隔离修改时使用,比如要把一段数据传给第三方库且不能影响原 buffer。
多个 TypedArray 共享一个 ArrayBuffer
同一块内存可以同时被不同类型的视图访问,无需转换或复制:
- 用
Uint8Array逐字节解析网络收到的原始二进制流 - 用
Int16Array把相邻两字节当有符号短整型(如音频 PCM 数据) - 用
Float32Array将同一区域当作浮点数组参与数学运算
所有操作都直接作用于原始 buffer,改一个视图,其他视图立刻可见变化 —— 这是真正意义上的“零拷贝共享”。
立即学习“Java免费学习笔记(深入)”;
配合 transferable 机制跨线程移动(非复制)
structuredClone() 是深拷贝,它复制;而 postMessage(data, transferList) 是转移,它把 ArrayBuffer 所有权移出当前上下文:
- 主线程创建大 buffer → 调用
worker.postMessage(buf, [buf])→ buf 在主线程变为空,Worker 中拿到的是同一块物理内存 - 这种 transfer 不涉及字节复制,毫秒级完成,适合音视频帧、大型模型权重等场景
- 注意:transfer 后原变量不可再访问,否则报错;transfer 不适用于 structuredClone,它只用于 postMessage
谨慎使用 TextEncoder/TextDecoder 和 base64
它们看似“转换”,实则隐含完整拷贝:
-
encoder.encode(str)返回新 Uint8Array,内容是 str 的 UTF-8 字节 —— 一次分配 + 一次拷贝 -
btoa()和atob()只支持 ASCII 子集,遇到非 ASCII 字节会失败;base64ArrayBuffer()类函数内部必然遍历+编码,无法避免拷贝 - 若只需传输或存储,优先用 Blob + URL.createObjectURL() 或直接发送 ArrayBuffer;若必须文本化,考虑更轻量的方案(如 hex 编码单字节)
不复杂但容易忽略:真正零拷贝的前提,是全程保持对 ArrayBuffer 的引用,并通过视图操作它。一旦转成字符串、普通数组、JSON 或跨 realm 传递未 transfer,拷贝就已发生。


















