最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Web Worker consumes massive amount of memory - Stack Overflow

programmeradmin4浏览0评论

I am trying to improve performance in my app which pares content of two large canvases.

The problem is that during parison main thread of the browser is blocked what results unresponsive UI. Execution time of parison function takes approx 10ms and parison happens every 250ms or 500ms.

To solve that problem I came up with idea of use another thread by creating a web worker. It works pretty nice right now, but I realized that it consumes insane amount of memory (up to 600MB in FF and Chrome - in Edge it's up to 70MB, it never reached 100MB in single thread version on all browsers).

I thought that I left some references and Garbage Collector can't release memory. However, after some time (whole day of stripping my app to the pieces and trying to delete, null or undefined variables/data) I created fiddle below in which I'm sending 1MB ArrayBuffer (even though I passed it by transferring) but without any processing and as you can see it consumes massive amount of memory too.

Any ideas how I can solve that problem (any alternative solutions or any possible worker improvements) and where the problem is?

var sortFilterDataWorker = function () {
    onmessage = function image2pare(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
  , pareWorker = new Worker(blobUrl) 
  ;

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

FIDDLE

EDIT:

I found out that if I terminate worker every n repeats and create new one releases memory faster. But it's still not a solution just a curio.

I am trying to improve performance in my app which pares content of two large canvases.

The problem is that during parison main thread of the browser is blocked what results unresponsive UI. Execution time of parison function takes approx 10ms and parison happens every 250ms or 500ms.

To solve that problem I came up with idea of use another thread by creating a web worker. It works pretty nice right now, but I realized that it consumes insane amount of memory (up to 600MB in FF and Chrome - in Edge it's up to 70MB, it never reached 100MB in single thread version on all browsers).

I thought that I left some references and Garbage Collector can't release memory. However, after some time (whole day of stripping my app to the pieces and trying to delete, null or undefined variables/data) I created fiddle below in which I'm sending 1MB ArrayBuffer (even though I passed it by transferring) but without any processing and as you can see it consumes massive amount of memory too.

Any ideas how I can solve that problem (any alternative solutions or any possible worker improvements) and where the problem is?

var sortFilterDataWorker = function () {
    onmessage = function image2pare(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
  , pareWorker = new Worker(blobUrl) 
  ;

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

FIDDLE

EDIT:

I found out that if I terminate worker every n repeats and create new one releases memory faster. But it's still not a solution just a curio.

Share Improve this question edited Jan 27, 2016 at 9:00 LJ Wadowski asked Jan 25, 2016 at 22:30 LJ WadowskiLJ Wadowski 6,72011 gold badges47 silver badges77 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 13 +50

I found that if I run the garbage collector manually from developer tools -> Timeline it clears out all of the memory. Similarly, if I begin interacting with the Worker context from the console, calling functions seems to randomly trigger successful gc.

Based on this, I would say that there is not a hanging reference, but that receiving objects via a transfer may not force a gc check as new allocation requests would.

Transferring the object back with a response seems to workaround the problem:

postMessage('hi', [ev.data]);  // process usage stays around 50MB

As an alternative, making sure the Worker is non-trivial and will need to do normal allocations also seems to properly trigger gc, i.e:

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

评论列表(0)

  1. 暂无评论