2011-07-01 6 views
0

자바 스크립트 코드에서 메모리 문제가 발생합니다. 나는 자바 스크립트에서 메모리 누수 패턴을 온라인으로 검색했지만 패턴 중 아무 것도 내 코드에 적용되지 않는 것 같다. 아주 간단한 코드이고, 클로저가없고, 내부 함수도 없으며, 모든 변수는 DOM 객체 나 부울과 같은 단순한 값만 가지고 있습니다. 심지어 변수에 속성을 정의하지도 않습니다. 그러나 어쨌든 필자는 Firefox (3.6.11)가 멈추고 IE에서 73 행의 메모리가 부족하다는 사실을 알게 된 많은 메모리가 누출 될 수 있습니다. DOM 트리에서 참조가있는 함수는 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 to 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 to "+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> 

답변

0

이 두 함수가 서로 호출한다는 사실과 관련이 있으며, 내가 말할 수있는 한 if 문은 항상 사실 일 것이라고 생각합니다. 효과적으로

function removeForm(span) { 
    if (previousSpan == null) return false; < --Out of memory here according to 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"; 
    } 
} 

:

var previousSpan; 

function removeForm(span) { 
    // ... 
    if(span == previousSpan) collapse(previousSpan); 
    // ... 
} 

function collapse(span) { // <---here span is previousSpan, 
     // <-- always true because you're doing if(previousSpan == previousSpan) 
    if (previousSpan == span) removeForm(span); 
    // ... 
} 

// This makes subsequent comparisons in "removeForm()" always true as well, 
// because now it is guaranteed that "span" is the same as "previousSpan" 

그래서 removeForm()에 한 번 span == previousSpan, 당신은 collapse()previousSpan을 전달하고 있습니다. collapse()이하는 첫 번째 일은 수신 한 내용이 previousSpan과 같은지 확인하는 것입니다. 그 이유는 처음부터 보내야하는 테스트이기 때문에 항상 그렇습니다.

+0

네, 다시 옳아 요. 그리고 나는 지금 정말로 어리 석다. 도움을 주셔서 감사합니다. 정말 감사드립니다. 나는 어제 몇 시간 동안이 코드를보고 있었고 그것을 보지 못했습니다. –

+0

글쎄, 내가 가진 모든 대답은 정확했다. 왜냐하면 그게 '그래픽'을 포함하고 있기 때문이다. 다시 한번 감사드립니다. –

+0

@Dude Dawg : 네, 거기에 있었으니 ... 오신 것을 환영합니다. – user113716

1

무한 루프가 진행중인 것처럼 보입니다.

removeFormcollapse

collapse 전화 removeForm

+0

오, 젠장, 네가 맞다고 생각해! 얼마나 어리석은가. 고마워요. 당신이 도와 줘서 다행이에요! –

0

내가 좋은 치아 빗이 이상 갈 시간이 걸릴하지 않을거야 호출합니다. 하지만 removeForm은 이라고하는 collapse으로 전화를 걸 때가 있습니다. 내가 의심스럽게 생각하는 첫 번째 것은이 두 함수가 어떻게 든 무한 재귀 패턴으로 서로를 호출한다는 것입니다.

이러한 기능 중 하나의 시작 부분에 중단 점을 넣으십시오.

디버거에서이 중단 점에 도달 할 때마다 호출 스택의 크기를 확인하십시오. 프로그램이 메모리가 부족해질 때까지 호출 스택이 확장되면 축하합니다. StackOverflow에 실제 스택 오버플로가 게시되었습니다.

+0

어제 몇 시간 동안이 코드를 실제로 보았지만 나는 그 점을 발견하지 못했습니다. 이제 올바른 대답을 선택하기 위해 모든 대답이 옳았 기 때문에 가장 많은 텍스트가 들어있는 대답을 선택하려고합니다. –

+0

게시물의 왼쪽에있는 숫자 옆에있는 "위로"화살표를 클릭하면 도움이되는 게시물에 투표 할 수 있습니다. –

관련 문제