是否有可能发现在浏览器中输入数组分配限制? [英] Is it possible to discover the typed array allocation limit in the browser?
问题描述
与内存池pre分配进行实验,我发现,分配60M Float32Array使得有时会死机的浏览器选项卡(在Chrome尝试):
VAR bigArray =新Float32Array(6000)
对于(VAR I = 0; I< bigArray.length; I + = 1){
bigArray [I] =的Math.random()
}
我一个8GB的机器上分配总(即Float32Array.BYTES_PER_ELEMENT * bigArray.length)240MB。这使得标签崩溃的时候20%和100%,如果我尝试检查bigArray(例如,尝试在控制台得到bigArray.length,记录它,更有甚者将鼠标悬停在它以查看其内容)。
有没有办法在现代浏览器(主要是Firefox和Chrome)(非标准的,复杂的随意)来计算分配限制?我想preallocate接近涨停池,并使用该池中所有我后来float数组需要 - 我不严格需要分配60M Float32Array,但我想弄清楚的最大合理池,我可以尝试没有颠簸我的标签分配。
填充一个大的缓冲区像这样需要一些时间,直到铬说不够可能会阻止浏览器。
您需要打破它的块,这样浏览器就可以在一段时间深呼吸一次。这将需要一个异步的方式。
除了来自:即使浏览器有一个任意的内存限制,它不应该,即使填充需要很短的时间崩溃的标签。如果内存用完分页会被系统调用被这样也是在这里应该不会有太大的问题(速度较慢,但可用)。如果仍然与溶液崩溃下面我会说这将是一个bug(考虑再报告给crbug.com)。
下面是异步填充大的缓冲区的一种方式:
函数getFilledFloat32(大小,回调){\r
尝试{\r
VAR bigArray =新Float32Array(大小),//分配缓冲区\r
BLOCKSIZE = 2 * 1024 * 1024,// 2MB块\r
块=块大小,电流= 0; //初始化块中断和位置\r
\r
(函数填充(){\r
而(电流I的大小和放大器;&安培; block--)\r
bigArray [电流++] =的Math.random(); //填写缓冲区,直到年底或块\r
\r
如果(电流I的大小){//是块\r
块=块大小; //重新设置块大小\r
document.querySelector('跨')的innerHTML + =。 //!仅用于演示\r
的setTimeout(填充,7); //等待7毫秒,继续\r
}\r
否则回调(bigArray)//我们就大功告成了,调用回调\r
})();\r
}赶上(ERR){\r
警报(错误:+ err.message);\r
}\r
}\r
\r
// ---测试code ----------------------------\r
\r
VAR isBusy = FALSE;\r
功能补(){\r
如果(isBusy)回报;\r
isBusy = TRUE;\r
VAR MB = +的document.getElementById(rngMem)值。\r
document.querySelector('跨')的innerHTML =填充。\r
getFilledFloat32(MB * 1024 * 1024,功能(缓冲){\r
警报(!先做了两个指标:\\ n+缓冲[0] +\\ n+缓冲[1]);\r
isBusy = FALSE;\r
});\r
}
\r
<标签=MEM>在MB大小:LT; /标签>\r
<输入ID =rngMem的onchange =。document.querySelector('输出')值= THIS.VALUE类型=范围分= 10最大值= 500 =值60 GT;\r
&所述;输出与GT; 60℃/输出GT;\r
<按钮的onclick =填写()>填写< /按钮>\r
< BR><跨度>< / SPAN>
\r
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.
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>
这篇关于是否有可能发现在浏览器中输入数组分配限制?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!