Javascript Web Worker/Canvas内存泄漏

Javascript Web Worker/Canvas内存泄漏,javascript,multithreading,memory,canvas,worker,Javascript,Multithreading,Memory,Canvas,Worker,小提琴: 使用Chrome,启动任务管理器(Shift+ESC),单击worker反转按钮几次,每次都会增加~10 MB。每当我收到来自工作线程的消息时,内存就会增加,这不是因为修改或访问画布,而是在工作线程将消息发送回主线程时发生的。消息越大,情况就越糟 将ImageData缓冲区添加到postMessage上可选的可转移的列表中并没有什么区别,同样的结果,我想知道是否有其他方法可以实现这一点 imageData = ctx.getImageData(0, 0, 800, 600);

小提琴:

使用Chrome,启动任务管理器(Shift+ESC),单击worker反转按钮几次,每次都会增加~10 MB。每当我收到来自工作线程的消息时,内存就会增加,这不是因为修改或访问画布,而是在工作线程将消息发送回主线程时发生的。消息越大,情况就越糟

将ImageData缓冲区添加到postMessage上可选的可转移的列表中并没有什么区别,同样的结果,我想知道是否有其他方法可以实现这一点

  imageData = ctx.getImageData(0, 0, 800, 600);
  worker.postMessage(imageData, [imageData.data.buffer]);
主线程和/或工作线程是否正在转移所有权仍然无关紧要。我可以在控制台中看到imageData对象实际上转移了所有权,但内存仍然在增加!我曾尝试使用chrome开发工具进行内存分析,但我看不出内存的增长在哪里

在dev工具中强制执行GC将清除内存。有时GC自动运行,有时不自动运行,当它运行时,它只释放分配的10%

昨晚我读了很多书,但他们都说了同样的话,我觉得我忽略了一些简单的事情

可转让对象:

更新 Chrome版本48.0.2564.116 beta-m(64位)

小提琴:


添加了一个循环选项,似乎释放内存的唯一方法是终止线程,但我想避免每次创建新线程,只保留一个线程打开,因为每次创建新线程时都会有明显的延迟,而不会出现内存泄漏。这只是正常的GC行为,您无法做多少事情来停止看似过度的内存使用

我玩了一个游戏,你的小提琴改变了代码,因此
worker.onmessage
函数立即调用
startWork
,有效地将其放入一个循环中,发送数据,接收反向数据集,将其放在画布上,然后再次调用
startWork
,在我喝咖啡时让它离开。它运行得很好


在chrome 49.0.2623.47 beta-m上观看进程时,内存使用量约为110mb,但从未耗尽内存。堆分配和时间轴都显示正常行为,没有泄漏。Chrome对GC做了一些修改,所以它推迟了对DOM和Javascript的操作,若你们不习惯的话,这看起来就像内存使用量增加了一样,没什么好担心的。重要的是,当你需要内存时,它是可用的。如果内存严重不足,GC会进行清理,最好是有一些死内存,而不是在DOM或Javascript繁忙时阻塞它们,只是为了转储一些不需要的内存。

我在Chrome中找到了一个适合我的解决方案。我对你的小提琴的循环版本做了两个主要修改:

  • 从工作者返回时,将
    imageData.data.buffer
    添加到传输列表中
  • 传递键入的数组,
    imageData.data
    ,而不是整个imageData对象
  • 这是修改过的小提琴:

    注意,仅仅将缓冲区添加到worker的传输列表是不起作用的()我必须只传输类型化数组


    Chrome版本52.0.2743.116(64位)

    我认为你应该与Chrome人合作。在任务管理器中,您可以右键单击并添加“JavaScript内存”列。您会注意到,虽然选项卡中使用的实际内存增加了,但Javascript使用的内存量保持不变。这似乎表明一个问题超出了你的控制范围(至少从我的理解来看)。在Firefox上,这些版本似乎都不适合我——如果有人能解决这个问题,我会非常感兴趣。