Adding to WeakSet and Still Managing Memory Deletion

This is something strange that I noticed. The following code should not explode memory when using WeakSet , and obviously, other links do not linger:

 'use strict'; require('babel-polyfill'); const s = new WeakSet(); for (let i = 0 ; ; i++) { s.add({}); if (i % 100000 === 0) console.log(`${i} :${process.memoryUsage().heapUsed}`); } 

(SCCE github repo here ).

And yet, delete the memory it makes (in Node v4.3.2 with Babel translation):

 <--- Last few GCs ---> 165 ms: Scavenge 13.6 (48.0) -> 13.6 (48.0) MB, 14.4 / 0 ms [allocation failure]. 189 ms: Scavenge 14.4 (48.0) -> 14.4 (52.0) MB, 17.6 / 0 ms [allocation failure]. 340 ms: Scavenge 37.5 (68.0) -> 37.5 (68.0) MB, 35.2 / 0 ms [allocation failure]. 380 ms: Scavenge 38.3 (68.0) -> 38.3 (76.0) MB, 35.5 / 0 ms [allocation failure]. 567 ms: Scavenge 53.5 (76.0) -> 53.4 (77.0) MB, 74.6 / 0 ms [allocation failure]. <--- JS stacktrace ---> ==== JS stack trace ========================================= Security context: 0x228b1a4b4629 <JS Object> 1: add [native weak-collection.js:~92] [pc=0x2b4d202650b5] (this=0x386dbd0641f9 <JS WeakSet>,l=0x389216b5e19 <an Object with map 0x21f1c4616e79>) 2: /* anonymous */ [/home/mperdikeas/weak-set-blows-memory/es5/app.js:~1] [pc=0x2b4d20269023] (this=0x386dbd064221 <an Object with map 0x3193b8408829>,exports=0x228b1a4041b9 <undefined>,require=0x228b1a4041b9 <undefined>,module=0x228b1a4041b9 ... FATAL ERROR: invalid table size Allocation failed - process out of memory Aborted (core dumped) npm ERR! Linux 3.16.0-48-generic npm ERR! argv "/usr/bin/nodejs" "/usr/bin/npm" "run" "start" npm ERR! node v4.3.2 npm ERR! npm v2.14.12 npm ERR! code ELIFECYCLE npm ERR! simple-babel-serverside-node-only-archetype@1.0.0 start: `node es5/app.js` npm ERR! Exit status 134 npm ERR! 
+6
source share
2 answers

Refresh Bug fixed. The move was fixed in v8 5.0, which is used by Node 6.0, so in a few weeks you will have a version of Node, which it is fixed.


This is a bug in v8 . Your code, as indicated, should work fine. The problem basically lies in the fact that v8 does not perform full garbage collection, but only minimal garbage collection in this case.

This doesn't work fine in Chrome, the only reason it doesn't leak in Chrome is because other objects are created and can be freed - these objects can release triggers with a complete garbage collection, which also clears WeakSet .

WeakSet happens initially, for it core-js there is a smart polyfill, but it is actually not 100% weak, is used here or does matter.

+6
source

The following code does not leak in Chrome 49:

 'use strict'; const s = new WeakSet(); let j = 0; function f(){ for (let i = 0 ; i<100000; i++) { s.add({}); } console.log(`${j++} :${0|(performance.memory.usedJSHeapSize/(1024*1024))}MB`); return Promise.resolve(null).then(f); } f() 

So, this seems like an error in Node.js (it also plays in version 5.1.1.10). I filled for this in Node.js bugtracker .

+3
source

All Articles