SharedArrayBuffer 是 JavaScript 中实现 Worker 间真正共享内存的核心机制,需配合 TypedArray 和 Atomics 使用,且依赖跨域隔离策略启用。

SharedArrayBuffer 是 JavaScript 中实现 Worker 之间真正共享内存的核心机制,它允许多个线程(如主线程与 Web Worker,或多个 Worker 之间)直接读写同一块内存区域,从而避免序列化/反序列化的开销,提升高性能计算、实时音视频处理、游戏逻辑同步等场景的效率。
SharedArrayBuffer 的基本用法
SharedArrayBuffer 本身不提供读写能力,需配合 TypedArray(如 Int32Array、Float64Array)使用:
- 创建 SharedArrayBuffer:需指定字节长度(必须是整数,且现代浏览器通常要求为 4096 字节对齐以提升性能)
- 用 TypedArray 包装它,获得可操作的视图
- 通过
.postMessage(buffer, [buffer])将 buffer 转移给 Worker(注意:必须在 transfer list 中显式传入,否则只传递拷贝)
示例(主线程):
const sab = new SharedArrayBuffer(1024);<br>const sharedInts = new Int32Array(sab);<br><br>// 初始化一个标志位(用于同步)<br>Atomics.store(sharedInts, 0, 0); // 索引 0 设为 0<br><br>// 启动 Worker 并传入共享内存<br>const worker = new Worker('worker.js');<br>worker.postMessage({ sab }, [sab]); // 关键:[sab] 表示转移所有权
跨 Worker 同步:必须用 Atomics
多个 Worker 同时读写 SharedArrayBuffer 时,普通赋值(arr[i] = 1)不是原子操作,可能导致竞态条件。因此所有共享内存的读写和同步都必须通过 Atomics API:
立即学习“Java免费学习笔记(深入)”;
-
Atomics.load(arr, index):安全读取 -
Atomics.store(arr, index, value):安全写入 -
Atomics.add(arr, index, delta):原子加法(常用于计数器) -
Atomics.wait(arr, index, expectedValue, timeout)+Atomics.notify():实现阻塞等待与唤醒(类似条件变量)
例如 Worker 中等待主线程“发号”:
// worker.js<br>self.onmessage = ({ data: { sab } }) => {<br> const shared = new Int32Array(sab);<br> // 等待索引 0 变为 1<br> Atomics.wait(shared, 0, 0);<br> console.log('收到指令,开始执行');<br>};
主线程随后触发:
Atomics.store(sharedInts, 0, 1);<br>Atomics.notify(sharedInts, 0, 1); // 唤醒最多 1 个等待者
安全限制与启用条件
出于 Spectre 等侧信道攻击防护,SharedArrayBuffer 在大多数浏览器中默认被禁用,需满足以下跨域隔离(Cross-Origin Isolation)条件才能启用:
- 服务器必须返回两个响应头:
Cross-Origin-Embedder-Policy: require-corp和Cross-Origin-Opener-Policy: same-origin - 页面内所有资源(脚本、iframe、图片等)必须同源或明确声明
crossorigin属性并被服务器允许 - 可通过
self.crossOriginIsolated检查当前环境是否满足条件
不满足时调用 new SharedArrayBuffer() 会抛出 TypeError。
典型应用场景与注意事项
SharedArrayBuffer 适合高吞吐、低延迟的协作任务,但不是万能方案:
- ✅ 适合:多 Worker 并行图像像素处理、物理引擎分块计算、音频缓冲区实时交换、自定义消息队列实现
- ❌ 不适合:简单配置传递、小量数据通信(此时 postMessage 更简洁安全)
- ⚠️ 注意:不能直接在 SharedArrayBuffer 上使用 JSON.stringify / Object.assign;无法存储对象或字符串,只能操作原始数值类型
- ⚠️ 注意:调试困难——Chrome DevTools 支持查看 SharedArrayBuffer 内容,但需手动创建 TypedArray 视图才能解析


















