当前位置:首页 > 技术 > 正文内容

浏览器如何实现共享内存以优化并发数据访问

访客 技术 2026年9月8日 1

在浏览器环境中,SharedArrayBuffer (SAB) 是实现跨执行上下文(如 Web Worker)高效数据共享的关键。它允许在多个线程间直接访问同一块物理内存,避免了传统 postMessage 带来的数据复制开销,特别适用于性能要求极高的场景。

1. 浏览器并发模型与通信挑战

JavaScript 在主线程中运行,为避免 UI 阻塞,浏览器引入了 Web Worker、SharedWorker、ServiceWorker 以及 WebAssembly 线程等并发机制。这些 Worker 拥有独立的内存空间,通常通过 postMessage 进行通信。然而,postMessage 的数据复制(结构化克隆)机制在处理大量或频繁传输的数据时,会严重影响性能。

2. SharedArrayBuffer 与 Atomics:共享内存的核心

2.1 SharedArrayBuffer (SAB)

SharedArrayBuffer 对象代表一块可被多个线程同时访问的二进制内存区域。当一个线程将 SAB 传递给另一个线程时,传递的是内存的引用,而非数据副本。这意味着在一个线程中对 SAB 的修改,会立即被其他访问该 SAB 的线程感知。

// 主线程
const sharedBuffer = new SharedArrayBuffer(1024); // 1KB 共享内存
const int32Array = new Int32Array(sharedBuffer);

const workerThread = new Worker("worker.js");
workerThread.postMessage(sharedBuffer); // 传递引用,实现共享
// worker.js
onmessage = (event) => {
  const sharedArray = new Int32Array(event.data);
  sharedArray[0] = 42; // 修改共享内存,主线程可见
};

2.2 Atomics 原子操作

由于多线程并发访问同一内存,为了防止数据竞争(race condition)和保证操作的原子性,浏览器提供了 Atomics 对象。它提供了一系列安全读写共享内存的方法,并支持构建同步原语,如锁、信号量等。

// 安全地存储数据
Atomics.store(int32Array, 0, 123);
// 安全地加载数据
const currentValue = Atomics.load(int32Array, 0);
// 原子地增加值
Atomics.add(int32Array, 1, 1);
// 等待特定条件(阻塞当前线程)
Atomics.wait(int32Array, 2, 0); // 在位置2等待值0
// 通知等待中的线程
Atomics.notify(int32Array, 2, 1); // 通知位置2上的一个等待线程

3. 共享内存的典型应用场景

  • 并行计算:将大型数据集(如图像、视频帧、AI 模型数据)放入 SAB,由多个 Worker 并行处理,充分利用多核 CPU 提升计算密集型任务的效率。
  • 实时数据同步:在游戏、音视频处理、实时通信等应用中,利用 SAB 实现低延迟的数据交换,如共享帧缓冲区、音频样本等。
  • WebAssembly 多线程:Wasm 线程可以直接使用 SAB 进行高效的内存共享,使得在浏览器中运行高性能计算库(如物理引擎、机器学习框架)成为可能。
  • 跨 Tab/Worker 数据缓存:同源的多个页面或 Worker 可以通过 SAB 共享大型对象,避免重复加载和复制,显著降低内存占用和加载时间。

4. 安全性要求:COOP/COEP 头部

为了防范 Spectre 等侧信道攻击,SharedArrayBuffer 的使用受到安全限制。要启用 SAB,网页必须设置特定的 HTTP 响应头:

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
  

这两个头部(合称 COOP/COEP)确保了页面的隔离性和安全性。

5. 实际应用示例

应用领域 具体场景 关键技术
WebAssembly TensorFlow.js, OpenCV.js 的多线程版本 SharedArrayBuffer, Atomics
音视频处理 实时音频合成、视频帧缓冲共享 SharedArrayBuffer, AudioWorklet
游戏开发 物理引擎计算、AI 逻辑并行 SharedArrayBuffer, Worker 池
数据可视化 后台数据聚合与处理 SharedArrayBuffer, Web Worker
WebRTC 低延迟数据通道传输 SharedArrayBuffer, Atomics

6. 共享内存机制概览

  • SharedArrayBuffer核心共享内存对象。
  • Atomics提供线程安全的原子操作和同步工具。
  • 优点:数据无复制,性能高,延迟低。
  • 限制:需配置 COOP/COEP 安全头部。
  • 应用:并行计算、实时处理、AI、游戏等。

7. net::ERR_INSUFFICIENT_RESOURCES 错误解析

当浏览器报告 net::ERR_INSUFFICIENT_RESOURCES 错误时,通常意味着系统或浏览器内部的共享内存相关资源不足。这可能由以下原因引起:

  • 内存页粒度限制:现代操作系统以内存页(如 4KB)为单位分配共享内存。即使 SAB 很小,也至少占用一个内存页,并产生额外的内核对象和句柄。频繁创建大量小 SAB 会快速耗尽文件描述符或共享内存句柄的上限。
  • 同步原语资源耗尽:大量使用 Atomics.wait() / Atomics.notify() 会消耗浏览器内部的等待队列(类似 futex 机制)资源。
  • 安全隔离上下文限制:COOP/COEP 启用后,浏览器会严格管理共享内存的分配,当分配的共享内存句柄过多时,可能会主动拒绝新的分配请求。

7.1 典型触发场景

  • 创建数万个小尺寸(如 1KB)的 SAB。
  • Worker 线程中频繁地创建和销毁 SAB。
  • 在大量 SAB 上频繁执行 Atomics.wait/notify
  • 浏览器处于低资源模式(如移动设备)。

7.2 优化建议

  • 内存复用:优先创建一个大的 SharedArrayBuffer,并在其上创建多个视图(如 Int32ArrayUint8Array),而不是创建大量小的 SAB。
  • 控制线程数量:过多的 Worker 线程会成倍增加资源消耗。
  • 避免短生命周期 SAB:设计时尽量复用共享内存,减少创建和销毁的频率。
  • 合理设置 SAB 尺寸:建议每个 SAB 至少 64KB,以减少内存页碎片。
  • 监控资源:使用浏览器提供的性能分析工具(如 chrome://tracing)来诊断内存分配问题。

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。