2010-09-20 9 views
6

मैं डीओएम तत्वों के साथ गतिशील रूप से परिवर्तनीय डेटा को प्रदर्शित करने की कोशिश कर रहा हूं (उन्हें जोड़/हटा रहा हूं)। मुझे लगभग सभी ब्राउज़रों का एक बहुत ही अजीब व्यवहार पता चला: मैंने एक डोम तत्व हटा दिए जाने के बाद और फिर एक नया जोड़ा, ब्राउज़र हटाए गए डीओएम आइटम द्वारा ली गई मेमोरी को मुक्त नहीं कर रहा है। मेरा मतलब समझने के लिए नीचे दिया गया कोड देखें। इस पृष्ठ को चलाने के बाद यह 150 एमबी मेमोरी तक चरण-दर-चरण खाएगा। क्या कोई मुझे इस अजीब व्यवहार की व्याख्या कर सकता है? या शायद मैं कुछ गलत कर रहा हूँ?चक्रीय जोड़ना/डीओएम नोड्स को हटाने से जावास्क्रिप्ट में मेमोरी लीक हो जाती है?

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> 
<html> 
<head> 
    <script type="text/javascript"> 
    function redrawThings() { 
     // Removing all the children from the container 
     var cont = document.getElementById("container"); 
     while (cont.childNodes.length >= 1) { 
      cont.removeChild(cont.firstChild); 
     } 

     // adding 1000 new children to the container 
     for (var i = 0; i < 1000; i++) { 
      var newDiv = document.createElement('div'); 
      newDiv.innerHTML = "Preved medved " + i; 
      cont.appendChild(newDiv);    
     }   
    } 
    </script> 
    <style type="text/css"> 
    #container { 
     border: 1px solid blue; 
    } 
    </style> 
</head> 
<body onload='setInterval("redrawThings()", 200);'> 
    <div id="container"> </div> 
</body> 
</html> 
+0

बस एक तरफ ध्यान दें: ['setInterval'] (https://developer.mozilla.org/en/DOM/window.setInterval) पर पैरामीटर के रूप में स्ट्रिंग का उपयोग न करें:" इस वाक्यविन्यास का उपयोग करने की अनुशंसा नहीं की जाती है [eval()] (https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Global_Functions/Eval#Don%27t_use_eval%21) का उपयोग करने के समान कारणों के लिए " –

+0

नोट मार्सेल के लिए धन्यवाद! मुझे सिंटैक्स नहीं पता था। –

उत्तर

1

मैं एफएफ 3.6.8/लिनक्स पर इस पुन: पेश नहीं कर सकता है, लेकिन एक टाइमर के लिए 200 एमएस बल्कि डोम फिर से प्रतिपादन की है कि ज्यादा से छोटा है। मैं अपनी मशीन पर जो नोटिस करता हूं वह यह है कि इस स्क्रिप्ट को चलाने के अलावा जावास्क्रिप्ट-गहन चीजें करते समय, इस उत्तर बॉक्स में टाइपिंग की तरह, मेमोरी उपयोग बढ़ता है, लेकिन जब मैं टाइप करना बंद करता हूं तो फिर से रिलीज़ होता है (मेरे मामले में, स्मृति के लगभग 16% उपयोग)।

मुझे लगता है कि आपके मामले में ब्राउज़र के कचरा कलेक्टर में वास्तव में स्मृति से उन नोड्स को हटाने के लिए पर्याप्त 'खाली समय' नहीं है।

+0

मैंने कुछ और शोध किए और पाया कि मेरे शुरुआती निष्कर्ष गलत थे - ब्राउज़र स्मृति को ढीला नहीं करते हैं, वे इसे निश्चित मात्रा तक खाते हैं और फिर आवंटित स्मृति गिर जाती है (और फिर चरण-दर-चरण बढ़ने लगती है)। जैसे क्रोम की मेमोरी 150 एमबी तक बढ़ जाती है और फिर 75 एमबी तक जाती है (हालांकि शुरुआती 7 एमबी तक नहीं!), आईई मेमोरी खपत बिल्कुल बढ़ती नहीं है। अजीब, लेकिन स्टैक ओवरफ्लो पर पूछने से पहले मैंने क्रोम, आईई और एफएफ पर बढ़ती स्थिर स्मृति खपत देखी और चीजों के अनुसार काम करना शुरू कर दिया। पूछे गए सभी लोगों के लिए बहुत धन्यवाद! –

0

यह क्योंकि डोम पेड़ से एक नोड को हटाने स्मृति से वह हटता नहीं है, यह अभी भी सुलभ है, तो निम्न कोड काम करता रहेगा:

var removed = element.removeChild(element.firstChild); 
document.body.appendChild(removed); 

कि कोड element से पहले बच्चे को हटा देगा, और उसके बाद इसे हटा दिए जाने के बाद, इसे दस्तावेज़ के अंत में जोड़ दें। वास्तव में कुछ भी नहीं है जो आप अपने कोड को कम निकासी के साथ अधिक कुशल बनाने के अलावा कर सकते हैं।

अधिक जानकारी के लिए, मोज़िला डेवलपर सेंटर पर Node.removeChild पृष्ठ देखें।

+1

लेकिन यदि कुछ भी (जैसे ओपी में) को असाइन नहीं किया गया है तो कचरा कलेक्टर इसे स्मृति से हटा देगा। यह कारण नहीं है। – slebetman

+0

नहीं, यही कारण है, भले ही कचरा कलेक्टर को असाइन किया गया हो, इसे हटा नहीं पाएगा। यहां तक ​​कि 'हटाया गया = null' स्मृति से संदर्भ को नहीं हटाएगा, ऐसा करने का एकमात्र तरीका पृष्ठ को रीफ्रेश करना है। –

+0

हां, मैं पुष्टि कर सकता हूं: कचरा कलेक्टर मौजूद है और यह डीओएम वस्तुओं से हटा दिया जाता है। लेकिन यह विभिन्न ब्राउज़रों पर अलग-अलग काम करता है, उदा। क्रोम के एक व्यक्ति ने लगभग 150 एमबी तक पहुंचने के बाद ही अपने मामले में काम करना शुरू कर दिया। –

0

सुनिश्चित नहीं है कि यह समय को प्रभावित करेगा, और शायद यह वास्तव में खराब अभ्यास है, लेकिन बच्चे नोड्स के माध्यम से लूपिंग करने के बजाय, क्या आप div के आंतरिक HTML को "" सेट नहीं कर सकते ??

संबंधित मुद्दे