Reputation: 51
I'm new to javascript and seem to be having a bit of problem tracking down a memory leak. I've narrowed it down to a section that seems to cause the memory leak, since the code is fairly complex. I'll post a different example that trivializes it but causes the same problem (just much smaller).
Basically, I have some code that dynamically builds HTML and attaches events to the HTML. The HTML gets rebuild with every AJAX request. This all works fine and dandy the first time but after each AJAX request the browser memory goes up(not always equal)! This problem can be reproduced by clicking run multiple times on jsfiddle and watching the browsers memory. My assumption is that the closures that get created are never garbage collected but I'm not sure? If that is the case is there a better way to do this without closures that won't cause any problems?
This happens in FF8, latest version of Chrome, and IE 8. Most likely all others - just what I've tested.
I've put some comments in the code that should help.
Thanks!
EDIT: Ok, so after doing some more research using sIEve, I can see that the number of DOM nodes is doubling on every AJAX call. I've updated the example to simulate this. So my question is why aren't the DOM elements garbage collected after calling jQuery empty or remove functions? I've also looped through the elements in stuff unbinding the event handlers and setting each DOM element js reference to null with no impact...
Upvotes: 3
Views: 1283
Reputation: 1738
This has to do with the DOM's GC and the JavaScript GC not being friends. The basic gist is that if something is referenced by the DOM, the JS GC might not destroy it, and vice versa. This idea might be outdated, as it comes up in Crockford's book which is a few generations of browser old.
I see a few potential problems here, which might be specific to the JS Fiddle but might not be:
But I don't see any real problems, and after a few minutes my memory usage goes back down to normal.
In short, you don't have a memory leak (at least a pressing one), your JS interpreter's GC is just being lazy. You're abandoning a lot of DOM elements, which isn't good, and is the reason your memory is spiking, but that is a short-term performance hit, not a long-term page load issue.
Upvotes: 3
Reputation: 107536
I'm with ShaggyFrog on this one. You can decrease the memory allocation by removing local variables and emptying that appendUs
array manually when you're done with it. In Chrome, I saw the memory allocation jumping up by 800KB - 1MB on every run of your script. Making small changes to your code as described above reduced the additional memory allocation to 400 - 500KB on each run (on average, by manual observation of Task Manager).
With that said, the behavior could just be Windows and/or Chrome and their memory management. After leaving the JSFiddle page idle for a while, the memory usage for Chrome dropped back down to where it was before I started running your example. Some sort of garbage collection happened eventually, just maybe not as quickly as you are expecting it to happen.
Upvotes: 0
Reputation: 25164
There was a trick to reduce/avoid memory leaks, at least in IE.
You can try it to see if the memory is freed quicker than your current method.
It is to insert first the HTML in the DOM, and then attach the events.
Upvotes: 0
Reputation: 22719
You'll need to be careful about just looking at the browser's memory usage. A more accurate test with that as the measurement would be to run the code many times, then look at the browser memory usage, then run many more times and compare the new number.
Normally, the browser doesn't behave in a way that reflects just the use of javascript. So, it's memory usage can fluctuate without your code necessarily having a leak.
Upvotes: 0
Reputation: 27601
It's not uncommon for a program to allocate memory, see its memory usage go up and then not change when that memory is freed. This is a consequence of how the underlying OS is managing memory and is not necessarily cause for concern, and not necessarily a "problem". You should use other tools, in general, to locate memory leaks in programs (whether they are native code or live in a browser), instead of relying on system tools that track overall process statistics.
Upvotes: 1