是否可以在浏览器中发现类型化数组分配限制?

2024-02-16

通过内存池预分配实验,我发现分配 60M Float32Array 有时会导致浏览器选项卡崩溃(在 Chrome 中尝试过):

var bigArray = new Float32Array(60000000)
for (var i = 0; i < bigArray.length; i+=1) {
    bigArray[i] = Math.random()
}

我在 8Gb 机器上总共分配了 240MB(即 Float32Array.BYTES_PER_ELEMENT * bigArray.length)。这使得选项卡崩溃的次数为 20%,如果我尝试检查 bigArray(例如,尝试在控制台中获取 bigArray.length、记录它,或者更糟糕的是,将鼠标悬停在它上面以查看其内容),则该选项卡崩溃的次数为 100%。

现代浏览器(主要是Firefox和Chrome)有没有一种方法(非标准的,随意复杂的)来计算分配限制?我想预先分配一个接近限制的池,并使用该池来满足我所有后续的浮点数组需求 - 我并不严格需要分配 60M Float32Array,但我想找出我可以尝试分配的最大合理池不会破坏我的标签。


像这样填充一个大缓冲区需要一些时间,并且可能会阻止浏览器,直到 Chrome 说足够。

您需要将其分解为块,以便浏览器可以偶尔喘口气。这将需要异步方法。

除此之外:即使浏览器有任意内存限制,即使填充需要很短的时间,它也不应该使选项卡崩溃。如果内存耗尽,系统将调用分页,因此这里也不会有太大问题(速度较慢,但​​可用)。如果使用下面的解决方案仍然崩溃,我会说这将是一个错误(然后考虑将其报告给 crbug.com)。

这是异步填充大缓冲区的一种方法:

function getFilledFloat32(size, callback) {
  try {
    var bigArray = new Float32Array(size),        // allocate buffer
        blockSize = 2 * 1024*1024,                // 2mb blocks
        block = blockSize, current = 0;           // init block break and position

    (function fill() {
        while(current < size && block--)
             bigArray[current++] = Math.random(); // fill buffer until end or block
        
        if (current < size) {                     // was block
            block = blockSize;                    // reset block-size
            document.querySelector('span').innerHTML += "."; // !! just for demo
            setTimeout(fill, 7);                  // wait 7ms, continue
        }
        else callback(bigArray)                   // we're done, invoke callback
    })();
  } catch(err) {
    alert("Error: " + err.message);
  }
}

// --- test code ----------------------------

var isBusy = false;
function fill() {
  if (isBusy) return;
  isBusy = true;
  var mb = +document.getElementById("rngMem").value;
  document.querySelector('span').innerHTML = "Filling.";
  getFilledFloat32(mb * 1024*1024, function(buffer) {
    alert("Done! First two indexes:\n" + buffer[0] + ",\n" + buffer[1]);
    isBusy = false;
  });  
}
<label for="mem">Size in MB:</label>
<input id="rngMem" onchange="document.querySelector('output').value = this.value" type="range" min=10 max=500 value=60>
<output>60</output>
<button onclick="fill()">FILL</button>
<br><span></span>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是否可以在浏览器中发现类型化数组分配限制? 的相关文章

随机推荐