Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Web Worker消耗大量内存_Javascript_Multithreading_Google Chrome_Firefox_Web Worker - Fatal编程技术网

Javascript Web Worker消耗大量内存

Javascript Web Worker消耗大量内存,javascript,multithreading,google-chrome,firefox,web-worker,Javascript,Multithreading,Google Chrome,Firefox,Web Worker,我正在努力提高我的应用程序的性能,它比较了两张大画布的内容 问题在于,在比较期间,浏览器的主线程被阻塞,导致UI无响应。比较功能的执行时间约为10ms,每250ms或500ms进行一次比较 为了解决这个问题,我想出了通过创建webworker来使用另一个线程的想法。它现在运行得很好,但我意识到它消耗了惊人的内存(FF和Chrome的内存高达600MB,Edge的内存高达70MB,在所有浏览器上的单线程版本中从来没有达到100MB) 我想我留下了一些引用,垃圾收集器无法释放内存。然而,经过一段时间

我正在努力提高我的应用程序的性能,它比较了两张大画布的内容

问题在于,在比较期间,浏览器的主线程被阻塞,导致UI无响应。比较功能的执行时间约为10ms,每250ms或500ms进行一次比较

为了解决这个问题,我想出了通过创建
webworker
来使用另一个线程的想法。它现在运行得很好,但我意识到它消耗了惊人的内存(FF和Chrome的内存高达600MB,Edge的内存高达70MB,在所有浏览器上的单线程版本中从来没有达到100MB)

我想我留下了一些引用,垃圾收集器无法释放内存。然而,经过一段时间(整天把我的应用剥离成碎片,并试图
删除
null
未定义的
变量/数据),我创建了下面的fiddle,我在其中发送1MB
阵列缓冲
(即使我通过传输传递了它)但是没有任何处理,正如你所看到的,它也消耗了大量的内存

有什么想法可以解决这个问题(任何替代解决方案或任何可能的工人改进)以及问题在哪里

var sortFilterDataWorker = function () {
    onmessage = function image2compare(ev) {
      postMessage('hi');
    };
}.toString();

/* PREPARE WORKER AS STRING TO CREATE JS BLOB FILE */
sortFilterDataWorker = sortFilterDataWorker.slice(sortFilterDataWorker.indexOf('{') + 1, -1).trim();

var blob = new Blob([sortFilterDataWorker]) // create blob file with worker code
  , blobUrl = window.URL.createObjectURL(blob) // create pseudo url to blob file
  , compareWorker = new Worker(blobUrl) 
  ;

setInterval(function(){
  var oneMB = new ArrayBuffer(8388608);
  compareWorker.postMessage(oneMB, [oneMB]); // transpile ArrayBuffer
}, 250);

编辑:


我发现,如果我每n次重复终止一个worker并创建一个新的worker,那么释放内存的速度会更快。但它仍然不是一个解决方案,只是一个古董。

我发现,如果我从developer tools->Timeline手动运行垃圾收集器,它会清除所有内存。类似地,如果我从控制台开始与工作上下文交互,调用函数似乎会随机触发成功的gc

基于此,我认为不存在挂起引用,但通过传输接收对象可能不会像新的分配请求那样强制执行gc检查

通过响应将对象传输回来似乎可以解决问题:

postMessage('hi', [ev.data]);  // process usage stays around 50MB
另一种选择是,确保工作人员不琐碎且需要进行正常分配似乎也能正确触发gc,即:

  postMessage('hi');
  var twoMB = new ArrayBuffer(8388608); // usage cycles 70MB - ~220MB

谢谢@Etsitra,您的最小化测试用例非常完美。您还应该将bug直接提交到chromium.org和bugzilla,这样环境最终就可以满足您的需要,而无需采取变通措施。我上周确实报告了这一点,所以我希望他们能够修复它。不管怎样,在我实现了你的修复应用程序之后,它的性能终于达到了我的预期,再次感谢你!虽然这一修正有点帮助,但它并没有解决我的漏洞。gc经常运行并清除所有内存,但在这之后,内存消耗会更快,在两次gc运行之间达到越来越高的值。我有点不知所措…@Fuzzyma我的例子在加压和观察gc方面比试图优化它更好。尝试从用1字节数组分配替换引用开始的不太激烈的方法可能会有效地触发它,同时保留更少的资源。