Is it possible to discover the typed array allocation limit in the browser?

半世苍凉 提交于 2020-01-15 06:59:29

问题


Experimenting with memory pool pre-allocation, I found that allocating a 60M Float32Array makes sometimes crash the browser tab (tried in Chrome):

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

I'm allocating 240MB in total (i.e. Float32Array.BYTES_PER_ELEMENT * bigArray.length) on an 8Gb machine. That makes the tab crash 20% of times, and 100% if I try to inspect bigArray (e.g., try to get bigArray.length in console, log it or, worse, hover over it to see its contents).

Is there a way (nonstandard, complex at will) in modern browsers (mainly Firefox and Chrome) to calculate the allocation limit? I would like to preallocate a pool near the limit and use that pool for all my subsequent float array needs - I don't strictly need to allocate a 60M Float32Array, but I would like to figure out the maximum reasonable pool I can try to allocate without thrashing my tab.


回答1:


Filling a big buffer like this takes some time, and will probably block the browser until Chrome says enough.

You need to break it down in blocks so the browser can take a breath once in a while. This will require an asynchronous approach.

Besides from that: even if the browser has an arbitrary memory limit, it should not crash the tab even if the filling takes short time. If memory run out paging would by invoked by system so also here there should not be much of a problem (slower, but available). If it still crashes with the solution below I would say it would be a bug (consider then to report it to crbug.com).

Here is one way to fill a large buffer asynchronously:

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>


来源:https://stackoverflow.com/questions/29111339/is-it-possible-to-discover-the-typed-array-allocation-limit-in-the-browser

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!