admin管理员组

文章数量:1335713

The problem

Adding nodes, while removing the old ones from the DOM, doesn't discard the old nodes from memory. (not all of them at least, without apparent reason).

How to see this happening

(you already know this but anyway..)
right click the output area and inspect using Chrome developer tools. Click on the Timeline tab and then at the circle (dot) on the upper left side to start recording.

now click on the body element, and it will start adding and removing items every 300ms
(the removed nodes should be garbage collected).

Stop the recording, extend the data-sampling zone to maximum, and you will see on the bottom half of the screen, in green, the nodes. the expected graph would be going up and down (where down means nodes have been discarded properly by the GC).

Test pages

These 2 test pages are very primitive. of course in real life developers use templates which generates huge amount of text which should be converted into DOM and injected into the page, therefor the number of live DOM nodes in memory should be kept low, and removed ones must be discarded.

with jQuery - - After about 40 seconds the GC is getting crazy and stops collecting removed nodes, which causes inflation.

Naive way - - Also it seems nodes aren't being removed in a satisfying rate, and the number keeps growing and growing...

Question

Why is this happening, and how should one properly remove NODES so inflation won't occur?

The problem

Adding nodes, while removing the old ones from the DOM, doesn't discard the old nodes from memory. (not all of them at least, without apparent reason).

How to see this happening

(you already know this but anyway..)
right click the output area and inspect using Chrome developer tools. Click on the Timeline tab and then at the circle (dot) on the upper left side to start recording.

now click on the body element, and it will start adding and removing items every 300ms
(the removed nodes should be garbage collected).

Stop the recording, extend the data-sampling zone to maximum, and you will see on the bottom half of the screen, in green, the nodes. the expected graph would be going up and down (where down means nodes have been discarded properly by the GC).

Test pages

These 2 test pages are very primitive. of course in real life developers use templates which generates huge amount of text which should be converted into DOM and injected into the page, therefor the number of live DOM nodes in memory should be kept low, and removed ones must be discarded.

with jQuery - http://jsbin./lamigucuqogi/2/edit - After about 40 seconds the GC is getting crazy and stops collecting removed nodes, which causes inflation.

Naive way - http://jsbin./riref/2/edit - Also it seems nodes aren't being removed in a satisfying rate, and the number keeps growing and growing...

Question

Why is this happening, and how should one properly remove NODES so inflation won't occur?

Share Improve this question edited Feb 21, 2015 at 14:42 Milk Man 1,25014 silver badges21 bronze badges asked Oct 7, 2014 at 15:06 vsyncvsync 131k59 gold badges340 silver badges422 bronze badges 8
  • I don't get that result on my machine. Are you sure it's not a race condition? Do you get the same result with a longer interval? – user1106925 Commented Oct 7, 2014 at 15:43
  • I've tried for 1 minute. it reaches 100,000 nodes. I think in real apps that would be pretty crazy. I mean, why aren't them being collected as they are removed? and why are they being collected on the first example, then mysteriously stop being collected. What result are you seeing? are they being collected? – vsync Commented Oct 7, 2014 at 15:46
  • Which version of chrome? I'm on Chrome 37 64-bit (Linux). Yes, mine are being collected. – user1106925 Commented Oct 7, 2014 at 15:47
  • Version 37.0.2062.124 m / Windows 7 64bit – vsync Commented Oct 7, 2014 at 15:50
  • @squint - interesting. could you post your graph here? snapnote.io – vsync Commented Oct 7, 2014 at 15:50
 |  Show 3 more ments

1 Answer 1

Reset to default 7

You are mistaken. If you leave the example running for a significant period of time, then use the garbage can icon in the Dev Tools timeline to force a garbage collection you will observe that the nodes are freed.

Like any other JavaScript object, DOM nodes bee eligible for GC when they bee unreachable from GC Roots. Provided you do not retain any other references to removed nodes (in an array, for example), they bee unreachable once removed from the main document.

However, they are not garbage collected immediately - a GC run can take time, during which the main browser thread is blocked, so it only runs periodically. What you are seeing is a period during which the JavaScript engine has decided not to run the garbage collector. You shouldn't be concerned by this - your code does allow the garbage collector to free memory when it eventually runs.

Highly remended viewing - Addy Osmani's memory management masterclass.

本文标签: javascriptRemoving DOM nodes with proper GC (no leaks)Stack Overflow