WebAssembly 的内存模型是其安全性和性能的关键特性:
1. 线性内存
- WebAssembly 使用连续的线性内存空间,类似于 C/C++ 的内存模型
- 内存以字节为单位进行寻址,从 0 开始
- 默认初始大小为 0 页(每页 64KB),但可以动态增长
- 内存大小必须是 64KB 的整数倍
2. 内存管理
javascript// 创建 WebAssembly 内存 const memory = new WebAssembly.Memory({ initial: 10, // 初始 10 页 (640KB) maximum: 100 // 最大 100 页 (6.4MB) }); // 获取内存缓冲区 const buffer = memory.buffer; const view = new Uint8Array(buffer); // 访问和修改内存 view[0] = 42; console.log(view[0]); // 42
3. 内存导入导出
- WebAssembly 模块可以导入外部 JavaScript 创建的内存
- 也可以导出内部内存供 JavaScript 访问
- 这使得 JavaScript 和 WebAssembly 可以共享内存空间
4. 内存安全特性
- 边界检查:所有内存访问都会进行边界检查,防止缓冲区溢出
- 沙盒隔离:WebAssembly 无法直接访问宿主环境的内存
- 类型安全:WebAssembly 的类型系统确保内存操作的安全性
5. 内存增长
javascript// 动态增长内存 memory.grow(10); // 增加 10 页
- 可以在运行时动态增长内存
- 有最大内存限制(由创建时指定)
- 增长操作会重新分配内存,可能导致性能开销
6. 与 JavaScript 的内存交互
- 通过
TypedArray或DataView访问 WebAssembly 内存 - 需要注意字节序(Little-Endian)
- 大数据传输时,共享内存比复制更高效
7. 性能优化建议
- 预分配足够的内存,减少运行时增长操作
- 使用合适的 TypedArray 类型(Uint8Array、Int32Array、Float64Array 等)
- 避免频繁的内存分配和释放
- 对于复杂数据结构,考虑使用内存池技术
8. WebAssembly 堆栈
- WebAssembly 有自己的调用栈,与 JavaScript 的调用栈分离
- 栈空间大小有限制,递归深度需要注意
- 栈溢出会抛出异常