使用Web Workers(垃圾收集器)可能发生内存泄漏

时间:2011-09-14 19:40:04

标签: javascript html5 javascript-events garbage-collection web-worker

我有一个应用程序,在单击按钮后调用web worker。计算将移至工作人员以缓解UI并使其在计算过程中对用户操作做出响应。

一切顺利,大约0.8-1.5秒后工人发出回复。在worker.onmessage中,我执行所有需要的DOM操作。但是在此GC出现之后,根据CPU的不同,实际上会阻止UI 2秒或更长时间。这真让我感到困惑,因为UI阻塞是我想要阻止的。

以下是时间轴/内存控制台选项卡的屏幕截图:http://i.imgur.com/zUoHa.jpg

正如您所看到的,GC事件恰好在所有DOM操作之后发生。实际上只有一个重绘事件(使用DocumentFragment)。

主js代码:

var sortWorker = new Worker('js/contactsorter.js');
sortWorker.onmessage = function(e) {
    var messages = [];
    e.data.forEach(function(userDoc) {
        var contactSection = _drawContact(userDoc);
        messages.push(contactSection);
    });

    meta.append(messages); // this actually appends document fragment as a child
};

sortWorker.postMessage(postMessageData);

contactsorter.js(工人):

onmessage = function(e) {
    var uid, output = [], usersStat = {};

    // calculations...

    postMessage(output);
    close();
};

有没有办法在这个地方避免这些GC事件?

UPD:在我看来,GC事件的时间取决于发送给工人的数据量。 UPD2:关闭和启动后GC事件只发生两次,从而阻止UI不到一秒钟。 HM?

1 个答案:

答案 0 :(得分:4)

Web Workers要记住的一件事,特别是在您的示例中使用它们时,您将在将对象发送给工作者时克隆该对象。所以让我们用一个愚蠢的例子来讨论这个问题:

  1. 制作大对象(你在评论中说2M ...... wtf ...哇) - 在主线程中分配2M
  2. 发布到工作人员,仍然在主线程中2M,加上在主线程中创建为额外的任何额外的JSON化您的对象/数组,然后关闭到工作人员中的2M工人
  3. 在工人的那个傻瓜身上......这里主线程中的2M +只是坐在等待GC,现在可能发生,可能不会......在一定数量的新一代物体达到阈值后GC触发。 ..比如在创造大量新物品和dom元素之后或期间说:D
  4. 工作人员回复一条消息,让我们假设2M现在在主线程中重新创建了一个新的2M(yay),再加上de JSON化对象所需的任何绒毛内存对象......你会看到这是怎么回事
  5. 既然你说这是一个chrome应用程序(另一个评论),那么也许你可以重构你的代码以利用Transferable Objects来避免对象Cloning创建临时对象等。当然,使用可转移的对象你必须重组为一个数组缓冲区,这本身就是一个黑魔法。