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

标签 javascript google-chrome memory-management browser typed-arrays

试验内存池预分配,我发现分配一个 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)中是否有一种方法(非标准的,随意的)来计算分配限制?我想在限制附近预先分配一个池,并将该池用于我所有后续的 float 数组需求——我并不严格需要分配一个 60M Float32Array,但我想找出我可以尝试分配的最大合理池无需翻动我的标签。

最佳答案

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

你需要把它分解成 block ,这样浏览器就可以偶尔喘口气。这将需要一种异步方法。

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

关于javascript - 是否有可能在浏览器中发现类型化数组分配限制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29111339/

相关文章:

javascript - BigInt 的优化整数对数 base2

google-chrome - 简单的多div页面会使Chrome崩溃。

Java 计时器问题可能涉及将它们存储在列表中

c# - 为什么要使用小于 32 位的整数?

javascript - 创建网页插件。如何包含 css 和渲染元素?

javascript - 使用 getterSetter 从 ng-model Angular 无限摘要循环

JavaScript:如何确定用户浏览器是否为 Chrome?

Javascript 正则表达式在不应该的情况下匹配逗号

c - 如果我运行一个循环一百万次,我是否需要担心在每次迭代中声明 double 值?

javascript - 动态添加 HTML 到 jquery mobile 后刷新一个部分