是否有可能发现在浏览器中输入数组分配限制? [英] Is it possible to discover the typed array allocation limit in the browser?

查看:198
本文介绍了是否有可能发现在浏览器中输入数组分配限制?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

与内存池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)。

下面是异步填充大的缓冲区的一种方式:

\r
\r

函数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

\r
\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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆