分配 65536 个元素的数组后,AssemblyScript / WebAssembly 分配失败
Posted
技术标签:
【中文标题】分配 65536 个元素的数组后,AssemblyScript / WebAssembly 分配失败【英文标题】:AssemblyScript / WebAssembly fails allocation after 65536-element array allocated 【发布时间】:2021-10-22 09:07:00 【问题描述】:我在分配内存时遇到问题,并且在网上找不到任何关于此案例的参考资料。特别是,如果我分配一个包含 65536 个元素(不是字节)或更多元素的数组,任何后续分配(即使是很小的一个)都会“失败”——当它成功执行时,它会返回一个与最近分配的数组重叠的指针。
我正在使用数组。我不确定在这里使用 StaticArray、Array 或 Float32Array 是否会改变行为,但我已经尝试了所有这些,但似乎没有任何改进。
AssemblyScript:
export function empty(): t
return new Array<f32>(16)
export function makeArray(count: u32): arr
let arr = new Array<f32>(count * 16)
let j: u32
for (let i: u32 = 0; i < count; i++)
for (j = 0; j < 16; j++)
//logU32(i * 16 + j)
arr[i * 16 + j] = j as f32 + 1;
return arr
宿主 JS:
console.log("memory.buffer.byteLength",LinAlg.memory.buffer.byteLength)
matrixBuffer = LinAlg.Matrix4.makeArray(6000)
console.log("matrixBuffer pointer", matrixBuffer)
console.log("empty pointer", LinAlg.Matrix4.empty())
我的脚本中的一些相关日志记录:
memory.buffer.byteLength(JS登录):655360 请求分配一个包含多少元素的数组(在 WASM 中登录):96,000 初始化每个缓冲区后的 Array.length(登录 WASM):96,000 返回给JS的指针值:21216 随后分配的 16 元素数组的指针值:21,216如果我不分配第二个数组,则原始数组可以通过 __getArrayView() 在 JS 中用作 96,000 个元素的数组。就好像分配大数组有效,但会破坏内存分配器以进行任何后续操作。
理论上,我应该在堆中达到 byte (21,216 + 4 * 96,000) = 405,216,并且还剩下大约 250k 的内存。
提前感谢您提供的任何帮助!
【问题讨论】:
【参考方案1】:来自 AssemblyScript Discord 上的 dcode:
听起来初始数组被 GC 过早收集(另一个分配可能会触发 GC 步骤),可能是因为该数组既没有从 Wasm 内部引用,也没有在外部 __pined?
我可以确认将分配行更改为:
matrixBuffer = LinAlg.__pin(LinAlg.Matrix4.makeArray(6000))
解决了这个问题。
【讨论】:
以上是关于分配 65536 个元素的数组后,AssemblyScript / WebAssembly 分配失败的主要内容,如果未能解决你的问题,请参考以下文章