Javascript memory leak in simple code -
i'm having kind of memory problem in javascript code. i've been searching online memory leak patterns in javascript, none of patterns seem apply code. it's simple code, there no closures, don't have internal functions, variables merely hold simple values, dom objects or booleans, don't define properties in variables. yet somehow manage leak memory firefox (3.6.11) freezes , ie tells me i'm running out of memory @ line 73, i've marked line. functions there references in dom tree toggle, replyform , replyexpand.
<script type="text/javascript"> function toggle(expandable){ if(expandable.parentnode.getelementsbytagname("ul")[0].classname=="hide"){ expandable.parentnode.getelementsbytagname("ul")[0].classname="show"; expandable.innerhtml="▼"; } else{ expandable.parentnode.getelementsbytagname("ul")[0].classname="hide"; expandable.innerhtml="►"; } } var previousspan; function replyform(span,postid,op,commentid){ if(removeform(span)) return; previousspan=span; if(span.nextsibling!=null){ span.parentnode.insertbefore(form(span,postid,op,commentid),span.nextsibling); } else{ span.parentnode.appendchild(form(span,postid,op,commentid)); } } function removeform(span){ if(previousspan==null) return false; <-- out of memory here according ie if(previousspan.parentnode.getelementsbytagname("form").length!=0) previousspan.parentnode.removechild(span.parentnode.getelementsbytagname("form")[0]); var result=(span==previousspan); if(result) collapse(previousspan); previousspan=null; return result; } function form(span,postid,op,commentid){ var result= "<form id=\"commentform\" method=\"post\" action=\"http://innategamer.300mb.us/wp-comments-post.php\">\n"+ "<p>replying "+op+":</p>\n"+ "<p><label for=\"author\">name *</label><input id=\"author\" type=\"text\" aria-required=\"true\" size=\"30\" value=\"\" name=\"author\"></p>\n"+ "<p>email *<input id=\"email\" type=\"text\" aria-required=\"true\" size=\"30\" value=\"\" name=\"email\"></p>\n"+ "<p>website<input id=\"url\" type=\"text\" size=\"30\" value=\"\" name=\"url\"></p>\n"+ "<textarea id=\"comment\" aria-required=\"true\" rows=\"8\" cols=\"45\" name=\"comment\"></textarea>\n"+ "<input id=\"submit\" type=\"submit\" value=\"post comment\" name=\"submit\">\n"+ "<input id=\"comment_post_id\" type=\"hidden\" value=\""+postid+"\" name=\"comment_post_id\">\n"+ "<input id=\"comment_parent\" type=\"hidden\" value=\""+commentid+"\" name=\"comment_parent\">\n"+ "</form>"; var div=document.createelement('div'); div.innerhtml=result; return div.firstchild; } function replyexpand(span){ if(span.innerhtml.indexof("▼")!=-1) collapse(span); else expand(span); } function collapse(span){ if(previousspan==span) removeform(span); span.innerhtml=span.innerhtml.replace("▼","►"); while(span.nextsibling!=null){ span=span.nextsibling; if(span.classname=="comment-content show"); span.classname="comment-content hide"; } } function expand(span){ span.innerhtml=span.innerhtml.replace("►","▼"); while(span.nextsibling!=null){ span=span.nextsibling; if(span.classname=="comment-content hide"); span.classname="comment-content show"; } } </script>
i'd imagine has fact these 2 functions call each other, , far can tell, if
statements, once true, true.
function removeform(span) { if (previousspan == null) return false; < --out of memory here according ie if (previousspan.parentnode.getelementsbytagname("form").length != 0) previousspan.parentnode.removechild(span.parentnode.getelementsbytagname("form")[0]); var result = (span == previousspan); if (result) collapse(previousspan); // <--------------- previousspan = null; // | return result; // | } // | // | function collapse(span) { // | if (previousspan == span) removeform(span); // <-------- span.innerhtml = span.innerhtml.replace("▼", "►"); while (span.nextsibling != null) { span = span.nextsibling; if (span.classname == "comment-content show"); span.classname = "comment-content hide"; } }
effectively:
var previousspan; function removeform( span ) { // ... if( span == previousspan ) collapse(previousspan); // ... } function collapse( span ) { // <---here span previousspan, // <-- true because you're doing if(previousspan == previousspan) if (previousspan == span) removeform(span); // ... } // makes subsequent comparisons in "removeform()" true well, // because guaranteed "span" same "previousspan"
so once span == previousspan
in removeform()
, you're passing previousspan
collapse()
. first thing collapse()
checks see if received equal previousspan
, since test send in first place.
Comments
Post a Comment