2010-11-12 6 views
6

बस एक ऐसे ग्राहक से मुलाकात की जिसकी अपने अजाक्स वेबपैम में बड़ी मेमोरी लीक समस्याएं हैं।jquery append() के साथ डोम तत्व जोड़ना स्मृति को रिसाव करता है?

मैं नीचे दिए गए उदाहरण (http://home.orange.nl/jsrosman/)

का इन स्मृति रूपरेखा के लिए ड्रिप/चलनी का इस्तेमाल किया है: तो मैं इस समस्या को प्रदर्शित करने के लिए निम्न testcase बनाने का फैसला किया मामले सरल है:

<html> 
    <head>  
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.4.4.min.js"> 
</script>  
</head>  
<script type="text/javascript"> 

    var lihtml = "<li class='green'>this is a test text</li>"; 

    function populatelist() { 
     for (var i = 0; i < 10000; i++) { 
      $('#listparent').append(lihtml); 
     }  
    }  

    function clearlist() { 
     $('#listparent').empty(); 
     if (typeof (CollectGarbage) == "function") { 
      alert('gc'); 
      CollectGarbage(); 
     }  
    } 


    /* Alternative clearlist with Remove instead of Empty(), still leaks */ 
    function clearlist() { 
     /* test remove the parent itself instead of empty below */ 
     $('#listparent').remove(); 
     $('body').append("<ul id='listparent'>");   
     //$('#listparent').empty(); 
     if (typeof (CollectGarbage) == "function") { 
      alert('gc'); 
      CollectGarbage(); 
     } 
    } 

    /* Edit!, this is the most effective way to release memory so far */ 
    function clearlist() { 
    $('#listparent').html(""); 
    if (typeof (CollectGarbage) == "function") { 
     alert('gc'); 
     CollectGarbage(); 
    } 
} 
</html> 
</script> 

<body> 
    <button onclick="javascript:populatelist()">Populate list</button> 
    <button onclick="javascript:clearlist()">Clear list</button> 
    <ul id="listparent"> 
     <li>kjjk</li> 
    </ul>  
</body> 

</html> 

प्रत्येक पॉप्युलेट सूची पर क्लिक करें संलग्न कर देता है 10000 ली तत्वों (पाठ के रूप में प्रतिनिधित्व): मैं निम्नलिखित जावास्क्रिप्ट की है। क्लियरलिस्ट jquery खाली() को कॉल करता है जो माना जाता है कि डीओएम सबट्री को साफ़ करना चाहिए और इसे जीसी के लिए योग्य बनाना चाहिए।

तो मैं छलनी में इस मामले चलाने के लिए और हर बार के लिए मैं नए तत्व स्मृति उपयोग बढ़ जाती है संलग्न, मैं इसे कभी नहीं देखा है कचरा एकत्र करने या मुक्त स्मृति। यहां तक ​​कि जब रैम का उपयोग 1.5 जीबी तक पहुंच जाता है और भले ही मैं आईई के लिए स्पष्ट रूप से जीसी को कॉल करने का प्रयास करता हूं।

यह वही sympton मैं ग्राहक जो मेरे स्थैतिक सामग्री obv के बजाय सूची डेटा के लिए jQuery के अजाक्स इस्तेमाल किया पर देखा है।

क्या मैं गलत तरीके से डोम बना रहा हूं? क्या कोई मुझे बता सकता है कि यह कचरा क्यों नहीं है, मैं डीओएम तत्वों के लिए कोई अन्य संदर्भ नहीं देख सकता हूं कि उन्हें कचरा क्यों नहीं होना चाहिए। एक और अजीब व्यवहार यह है कि कभी-कभी जब मैं खाली सूची पर क्लिक करता हूं (जब jquery खाली() विधि कहा जा रहा है, तो कभी-कभी sIEve स्मृति उपयोग में भी वृद्धि होती है)?

अगर किसी के पास इनपुट है तो मैं बहुत खुश हूं।

अपडेट, मैंने $ ('# listparent') का उपयोग करने की कोशिश की। एचटीएमएल ("") जो कि डीओएम को सही ढंग से रिलीज़ करने लगता है, कम से कम इसे एसआईईवी में रिलीज़ किया जा रहा है। मुझे लगता है कि अब तक का सबसे अच्छा समाधान है, हालांकि मुझे कोई स्पष्टीकरण नहीं है कि क्यों निकालें() और खाली() काम नहीं कर रहा है। शायद वे केवल स्थिर रूप से जोड़े गए तत्वों के लिए काम करते हैं?

+0

बस जिज्ञासु, तो आप इस से अधिक ब्राउज़र में की कोशिश की है स्मृति जारी करने के लिए सबसे प्रभावी तरीका है? – Prescott

+0

कोई एसआईईवी केवल आईई में काम नहीं करता है, एफएफएक्स की कोशिश नहीं की है, ज्यादातर क्योंकि आईई इस प्रणाली में उपयोगकर्ताओं द्वारा उपयोग किया जाने वाला ब्राउज़र है। – user408346

+0

असल में $ ('# listparent')।एचटीएमएल (""); खाली() दोनों को छोड़कर बहुत बेहतर काम करता है और हटा देता है() और पूरे डोम को रिहा करता है। मैं भाषणहीन हूँ – user408346

उत्तर

1

हाँ आप एक बहुत बड़ा सुधार संभव के रूप में कुछ के रूप में तो

var lihtml = "<li class='green'>this is a test text</li>", 
    listring = ""; 

function populatelist() { 
     for (var i = 0; i < 10000; i++) { 
      listring += lihtml; 
     }  

     $('#listparent').append(listring); 

    }  
... 

सीमा डोम पहुँच की तरह smthg कर बना सकते हैं।

अंतर यह है कि आप 10 हजार परिशिष्टों के बजाय 1 एकल ऐपेंड बनाते हैं। आपको चक्रों के अंदर हमेशा डीओएम हेरफेर से बचने की आवश्यकता है

संपादित करें: खाली के बजाय() आपके उल ने उल को हटाने की कोशिश की है और फिर अचानक इसे फिर से बनाया है?

+0

यह एक अच्छा सुझाव है और मैंने कोशिश की, समस्या अभी भी बनी हुई है, फिर भी यह लीक और खाली है() डोम को मुक्त नहीं लग रहा है। गंभीरता से jquery में विश्वास खोने शुरू कर दिया। – user408346

+0

मैंने अपना उत्तर –

+1

संपादित किया है मैंने कोशिश की है(), यह अभी भी लीक है लेकिन शायद खाली से थोड़ा कम() जो रिलीज़ होने की बजाय स्मृति को बढ़ाने के लिए प्रतीत होता है। वास्तव में अजीब बात यह है कि $ ('# listparent')। Html (""); चाल करता है और पूरे डोम और रैम मेमोरी जारी करता है?! – user408346

1

मैं HTML स्ट्रिंग के लिए जोड़कर सुझाव देते हैं और उसके बाद डोम में जोड़ने से: जहां न तो खाली()

function populatelist() { 
    for (var i = 0; i < 10000; i++) { 
     //$('#listparent').append(lihtml); 
     lihtml += "<li class='green'>this is a test text</li>"; 
    }  
}  
populateList(); 
$('#listparent').append(lihtml); 
+0

नीचे जैसा ही है, अच्छा सुझाव है लेकिन रिसाव बनी हुई है। – user408346

0
$('#listparent').html(""); 

काम करता है या निकाल सकते हैं() किया था। काश मैं जानता था क्यों। मुझे लगता है कि यह एक समाधान है हालांकि।

/* यह अब तक */

function clearlist() { 
    $('#listparent').html(""); 
    if (typeof (CollectGarbage) == "function") { 
     alert('gc'); 
     CollectGarbage(); 
    } 
संबंधित मुद्दे