WebAssembly.Memory大小限制

在项目中对接到某个游戏时,加载完成后会提示“the browser could not allocate enough memory for the WebGL content. If you are the developer of this content, try allocating less memory to your WebGL build in the WebGL player setting”。


image.png

但同样的游戏在chrome里打开都很正常,很是疑惑就调试一番,看到libcef中报错Uncaught RangeError: WebAssembly.Memory(): could not allocate memory", source: https://xxxx.com/h5/Build/UnityLoader.js

查询 WebAssembly.Memory文档发现,它构造时有initial和可选参数maximum。

  • initial:WebAssembly 内存的初始大小,以 WebAssembly 页面为单位。
  • maximum: 以 WebAssembly 页面为单位,可允许 WebAssembly 内存的 最大值。当存在此属性时,此参数用于提示引擎预先保留内存。但是,引擎可能会忽略或限制此预留请求。通常情况下大多数 WebAssembly 模块不需要设置 最大值

注意: A WebAssembly 页面的大小为一个常量 65,536 字节,即64KB。

分别在控制台中使用 new WebAssembly.Memory({ initial: 2048})测试,发现libcef中只能申请两次(256M)。而Chrome(95.0.4638.54)中可以使用new WebAssembly.Memory({ initial: 10000})申请12次,总量上有区别。然后测试单次最大,libcef中最大使用new WebAssembly.Memory({ initial: 2690}),而Chrome(95.0.4638.54)中最大使用 65000 左右。

在libcef中申请一次2048页,内存增加了128M。


image.png

Unity

在异常中定位到以下代码(chrome的美化功能)


    var PAGE_SIZE = 16384;
    var WASM_PAGE_SIZE = 65536;
    var ASMJS_PAGE_SIZE = 16777216;
    var MIN_TOTAL_MEMORY = 16777216;
....

    var TOTAL_STACK = Module["TOTAL_STACK"] || 5242880;
    var TOTAL_MEMORY = Module["TOTAL_MEMORY"] || 268435456;
    if (TOTAL_MEMORY < TOTAL_STACK)
        Module.printErr("TOTAL_MEMORY should be larger than TOTAL_STACK, was " + TOTAL_MEMORY + "! (TOTAL_STACK=" + TOTAL_STACK + ")");
    if (Module["buffer"]) {
        buffer = Module["buffer"]
    } else {
        if (typeof WebAssembly === "object" && typeof WebAssembly.Memory === "function") {
            Module["wasmMemory"] = new WebAssembly.Memory({
                "initial": TOTAL_MEMORY / WASM_PAGE_SIZE
            });
            buffer = Module["wasmMemory"].buffer
        } else {
            buffer = new ArrayBuffer(TOTAL_MEMORY)
        }
        Module["buffer"] = buffer
    }

可以看出代码中TOTAL_MEMORY / WASM_PAGE_SIZE 为 4096~

一开始以为是cef版本的问题,现在使用的是83版本的Chromium。


image.png

然后升级到了cef 97,依然不行。
而使用cef-project中的cefclient或cefsimple程序(无论是新老版本的cef)打开页面,都能成功。

然后经过反复对比代码,然后将差异消除,甚至将cefsimple的代码全部拷贝到我们的工程内,依然不行。这时就得怀疑是编译选项的问题了,经过最比发现cefclient和cefsimple程序中设置了链接选项 “启用大地址”为“/LARGEADDRESSAWARE”,然后将我们的cef浏览器程序的这个链接选项也打开,则一切正常了。


image.png

你可能感兴趣的:(WebAssembly.Memory大小限制)