问题
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