传递具有数组缓冲区的大量对象时,Web worker会崩溃Chrome选项卡

时间:2013-07-30 19:01:22

标签: javascript performance crash web-worker

我有一个生成大量数据的应用程序。这些数据需要在可用之前进行处理(WebGL 3D应用程序)。因此,我创建了一个Web工作人员来进行处理,以防止阻止UI的其余部分。

问题是,当数据足够大时,第一次启动Web工作程序会导致Chrome中的选项卡崩溃并显示“Aw,Snap”消息。我在Web工作者的最开始设置了断点,它甚至没有进入Web工作者。尝试克隆postMessage()调用的数据时似乎崩溃了。

这是一般数据结构(尝试将这些数组传递给Web worker):

function MyClass(id) {
    var count32 = getSize();
    var count16 = count32 * 3;

    this.uint16    = new Uint16Array(count16);  // array buffer 1
    this.float32_a = new Float32Array(count32); // array buffer 2
    this.float32_b = new Float32Array(count32); // array buffer 3


    this.a = id;
    this.b = count32;
    this.c = new MyInnerClass();
    this.d = true;
    this.e = 6;
    this.f = {a: 1, b: 2, c: 3, d: 4};
    this.g = [];
}

function MyInnerClass() {
    this.a = -10;
    this.b = -20;
    this.c = -30;
    this.d =  10
    this.e =  20
    this.f =  30
}

问题在于数组缓冲区1,2和3.我有一个 MyClass 对象的数组,大约15,000个,并且大约97%的数组缓冲区具有少于200个元素。但对于剩余的3%,阵列缓冲区有1,000到40,000个元素。

有趣的是,如果我注释掉任何2个数组缓冲区,那么包含这些类的postMessage()就可以了。

另一个有趣的观点:如果我点击Chrome中开发工具中的“启动时暂停”复选框,postMessage()有时会工作,即使是所有3个数组缓冲区也是如此。否则,每次都会失败。

任何人都知道为什么会这样吗?我找不到关于我可能会遇到的数据约束的文档,或者其他奇怪的内部怪异。否则,我将最终重构我的代码以解决这个问题。

DEMO:我创建了一个jsfiddle来证明这一点:http://jsfiddle.net/GmvyJ/11/

如果您更改此小提琴中的数据最大尺寸(至15,000),请不要以这种方式保存,否则您将永远无法再访问该页面。

1 个答案:

答案 0 :(得分:1)

您是否尝试使用Transfer of Ownership将数据传递给Worker线程。当您传递大型数组缓冲区时,这将特别有用,这将要求您使用一个额外的参数更改postMessage调用postMessage(ObjectToTransfer,[ObjectToTransfer.buffer,.....]);

这样您可以克隆整个对象,但在该对象中传输Array Buffers。

结帐Using transferable objects from a Web Worker