I'm starting to track some memory leak I've got in my web game. I've found a recurring pattern that's leaking DOM nodes, but I can't figure out why. I'm not an expert at using chrome's dev tools but I'm learning.
The smallest example I could set up is this:
<div id = "main">
</div>
<button onclick ='reset();'> test </button>
<script>
function reset()
{
var Div = "<select></select>";
$("#main").html(Div);
}
</script>
JSFIDDLE LINK
In chrome, when I use the dev Tools and use the timeline, we can see that:
we got X DOM nodes when loading the jsfiddle page
if we use the 'test' button once, we got X+2 nodes
each subsequent use adds 3 nodes
These nodes never get GC'ed and I can't understand why. The issue is worse when you use <option> inside the <select> (that seem coherent with the fact that the parent node doesn't get GC'ed). The issue is also the same with <input> as far as I can see (with checkbox & radio at least).
It seems so simple that I'm obviously missing something easy, but what is it is beyond me.
Do you have any ideas how could I solve this? I've tried to use the heap snapshot, but since I'm not fully understanding it yet, I've gotten no results.
Edit : Edit to bump the question since I haven't found an answer as of yet.
I have also recently come across this issue using Chrome 43. It appears to be a bug in chrome itself and is fixed in Chrome 46 (Chrome Canary)
This generates elements in the deatached DOM tree - better explanation here .
This elements are C++ objects and not js ones.
I agree that nodes are being created on each click but as soon as I force GB with the approriate button, one could observe it plummeting.
Related
I'm new to javascript and I can't seem to figure out this thing which I reckon should be a no-brainer.
I'm using Jquery mobile. I would like to clone a div and update the IDs of the elements in it. This seems to work fine. However, I can't get the cloned select element to work properly. I doesn't seem to work - I can't select anything - after its been cloned. When I call an extra $('html').trigger('create'); on the page the select elements starts looking 'funny' (probably because it got enhanced a second time) but does works.
I've posted a simplified version of my code here: http://jsfiddle.net/cUBPF/1/
Does anyone have a suggestion for me?
Thanks!
I'm not experiencing any problems however I'm just using my desktop. My first thought is to avoid calling the $('html').trigger('create'); at all and simply do what you want to within the clone_button click but then again, I'm not really sure what you are doing.
Instead of doing all this, why not output 10 or 20 of these fields and the display:none/display:block them......I assume you will run into less compability issues this way and you really don't want to allow infinite amount of fields....your going to run into browser memory issues which is just going to cause more bugs.
I've been using firebug for years now but never to its full potential. i've never really done a great deal of javascript debugging with it.
Heres my problem:
I have an element on my page that is disappearing on mouseOver if the page had just one or two custom js files this would be pretty easy to debug. However the site has loads. (not my work) Can i use fire bug to track down the scrip that is causing my element to disappear?
i.e configure firebug to watch my element > refresh > mouseOver > See what script file and what line the event is on?
Thanks Guys.
Find the element in the HTML (using inspection), right click on the node and select Break On > Attribute Change.
After that put the mouse over and you'll get the trace to the place that modifies the node
PS: I better like Chrome debugger for such kind of work - it has better (from my personal opinion) stack trace info.
I'm loading 2 embedded svg-lets in a page. One animated one not. They're loaded in sequence with a setTimeout.
When I load the animated first all goes well, the animation starts as expected and the second static svg is correctly displayed afterwards. When I first load the second, and afterwards the animated one, the animation does not start.
Code is here: jsfiddle switch #svg1, and #svg2 in the javascript.
Upon browser checking I found out this is probably a webkit bug as chrome and safari both show this behavior FF 12 and Opera are well.
Can this be fixed with JS code or should I file a bug with webkit?
== Added
I think the question should be rephrased why the animation does not start after the svg is loaded with a settimeout.
As Jared investigated below it works when the element is present in the DOM and is reordered via dom manipulation into the focus element, Chrome and webkit need a kick with a beginElement() call to the animate element. This still doesn't work out for elements constructed from plain text. As I only do have a mac and I still consider this a hobby project I leave MS IE completely out of the loop.
Well, it took quite a bit longer than I anticipated, but I got it worked out. Basically, the method you were using with the semi-SVG and the regex on the markup, etc., was to say the least not quite the way to get it done.
The answer is to use svg DOM animation methods and attributes, especially to start/stop the animation when you want it to run. Apparently, Firefox was just fine with reinitializing the element and the animation just by manipulating the inner HTML/markup. Chrome (Webkit?), however, actually needs you to programmatically access and control the element. I have not checked in IE, Opera or Safari.
I redid the example, leaving out the arrow altogether, as it is unrelated to the problem. I instead concentrated on creating and testing the animation functionality. The critical points you were missing before were:
var $lasso = $('#lasso'),
animater = $lasso.find('animate')[0],
...
animater.beginElement();
...
animater.endElement();
Here is the demo I made, which is significantly different that what you have in your question:
http://jsfiddle.net/9hBfs/
What I call the "lasso" effect is still there, though.
I would reference the Mozilla Developer Network (MDN) site, as they have a lot of great information and are a highly trusted authority:
https://developer.mozilla.org/en/SVG
https://developer.mozilla.org/en/SVG/Element/animate
http://www.w3.org/TR/SVG11/animate.html#animation-mod
http://www.w3.org/TR/SVG11/animate.html#InterfaceElementTimeControl
http://www.w3.org/TR/SVG11/animate.html#RestartAttribute
The following piece of code, works correctly in Firefox and Chrome, but it gives me a headache in IE.
var anotherDiv= document.getElementById("anotherDiv");
var destination = document.getElementById("mySourceDiv");
destination.appendChild(anotherDiv);
I'm trying to get a Div element and place it inside another div.
I get an error message (in the debug console in IE) similar to "interface not supported", and points me to the appendChild line.
What I've seen is that the type of the destination variable is an object rather then a DOM element.
What can I do to append the anotherDiv to mySourceDiv?
I'm trying this in IE 8.
You probably will need something like an importNode, there are various cross browser solutions around. The issue is that each node has a corresponding document object on it, in IE and so called security doesn't play nice moving things from one document to another.
So, essentially it's doing a deep clone, but the difference between using cloneNode is that cloneNode also sets the document which you don't want.
This might get you going in the right direction:
IE support for DOM importNode
I'd recommend using a library designed to sort through the browser incompatibilities for you. I've personally found jQuery to be quite good. jQuery has an append function.
I still consider myself a novice with javascript...so be gentle :)
Is there a way to view all open events listeners on a page and perhaps to see any inifinte loops that may be running?
What is happening, is a page I'm trying to debug works fine. Nodes get added to the page dynamically via a drag and drop method. All works well, but as time goes on, it seems to get increasingly slower - meaning the mouse starts skipping and the such.
I don't know if this is because javascript stores stuff in memory and my memory is getting used up, or if because of the constant checking of elements on mousemove slows things down as more elements are added to the page.
So I thought I would ask what I thought to be the obvious of maybe eventListeners are piling up and I'm not realizing it, or maybe there is an inifinte loop that is not being closed out.
I have firebug, and feel like I've looked at everything. I've put in console.debug statements in the loops and they all seem to end fine.
Any debugging tips would be appreciated.
I would say definitely be careful of memory leaks, especially in IE.
Here's a good resource for learning Javascript:
www.javascriptkit.com
Specifically here are some useful articles:
http://www.javascriptkit.com/jsref/events.shtml
http://www.javascriptkit.com/javatutors/closuresleak/index.shtml
What you need is a JavaScript profiler. Google chrome has a built in under ctrl-shift-j > profiles. There is one available in firebug for firefox as well.