2

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.

4

1 Answer 1

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>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.