Web 工作线程/画布的内存泄漏
Memory leak with Web Worker / Canvas
小提琴:https://jsfiddle.net/eimmot/065wxa9o/9/
使用 Chrome,启动任务管理器 (Shift+ESC),单击工作线程反转按钮几次,每次上升 ~10 MB。每当我收到来自worker的消息时,内存都会增加,这不是由于修改或访问画布,而是在worker将消息发送回主线程时发生。消息越大,情况就越糟。
将 ImageData 缓冲区添加到 postMessage 上的可选可传输对象列表中并没有什么区别,相同的结果,我想知道是否有另一种方法应该解决这个问题。
imageData = ctx.getImageData(0, 0, 800, 600);
worker.postMessage(imageData, [imageData.data.buffer]);
主线程和/或工作线程是否正在转移所有权仍然无关紧要。我可以在控制台中看到 imageData 对象实际上转移了所有权,但内存仍然增加!我已经尝试过使用 chrome 开发工具进行内存分析,但我看不到增长在哪里。
在开发工具中强制使用 GC 会清除内存。有时 GC 会自动运行,有时不会,当它自动运行时,它只释放分配的 10%。
昨晚我读了很多页面,但它们都说了同样的事情,我觉得我忽略了一些简单的东西。
可传输对象:https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers#Passing_data_by_transferring_ownership_(transferable_objects)
更新
Chrome 版本 48.0.2564.116 beta-m(64 位)
小提琴:https://jsfiddle.net/eimmot/065wxa9o/13/
添加了一个循环选项,似乎释放内存的唯一方法是终止线程,我想避免每次都创建新线程并保持一个打开状态,因为每次创建新线程时都有明显的延迟
我在 Chrome 中找到了一个适合我的解决方案。我对你的小提琴的循环版本做了两个主要修改:
- 从工作人员返回时将
imageData.data.buffer
添加到转移列表 - 传递类型化数组,
imageData.data
,而不是整个 imageData 对象
这是修改后的小提琴:https://jsfiddle.net/065wxa9o/14/
请注意,仅将缓冲区添加到工作线程的传输列表中不起作用(https://jsfiddle.net/065wxa9o/15/)我必须只传输类型化数组。
Chrome 版本 52.0.2743.116(64 位)
您没有内存泄漏。这只是正常的 GC 行为,您无法阻止看似过多的内存使用。
我玩了你的小提琴更改代码,以便worker.onmessage
函数立即调用startWork
,有效地将其置于循环中,发送数据,接收倒置数据集,将其放在画布上,然后再次调用startWork
并在我喝咖啡时放手。它运行得很好。
在chrome 49.0.2623.47 beta-m上监视进程,内存使用量约为110mb,但从未耗尽内存。堆分配和时间线都显示正常行为且没有泄漏。Chrome 对 GC 进行了一些更改,以便它推迟其操作以支持 DOM 和 Javascript,如果您不习惯它,看起来内存使用量已经上升,这没什么可担心的。重要的是,当您需要内存时,它是可用的。如果内存严重不足,GC 会清理,最好有一些死内存,而不是在 DOM 或 Javascript 繁忙时阻塞它们,只是为了转储一些不需要的内存。
- 重复应用 d3 转换导致的内存泄漏
- IE7中的blockUI插件内存泄漏25kb
- Javascript闭包-如何防止内存泄漏
- jQuery Draggable:内存泄漏
- "检测到可能的EventEmitter内存泄漏”;使用Gulp+Watchify+Factor捆绑包
- 在Dojo类中递归调用setTimeout时是否存在内存泄漏
- 是内存泄漏
- 将处理程序留在img.onload上是内存泄漏
- 具有并发sse连接的node.js内存泄漏
- 简单对象的Javascript内存泄漏
- WeakMap是否会将我从父/子关系的内存泄漏中拯救出来
- Javascript绘制画布内存泄漏
- Node.js”;检测到EventEmitter内存泄漏”;
- 正在清理内存泄漏
- 递归Javascript对象是否会导致任何问题(内存泄漏)
- Angular JS$编译服务导致$watch内存泄漏
- 如何防止和防范闭包内存泄漏
- 跟踪 JavaScript 内存泄漏的工具
- 页面刷新后javascript内存泄漏有问题吗?为什么?
- XMLHttpRequest循环内存泄漏