Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> JavaScript

JavaScript में डिटैच्ड DOM एलिमेंट्स से मेमोरी लीक


डिटैच्ड DOM एलिमेंट्स और मेमोरी लीक

डिटैच्ड DOM एलिमेंट्स वे एलिमेंट्स हैं जो DOM से हटा दिए गए हैं लेकिन JavaScript रेफरेंस के कारण मेमोरी में बने रहते हैं। जब तक किसी वेरिएबल/ऑब्जेक्ट से रेफरेंस है, गार्बेज कलेक्टर इन्हें साफ नहीं कर सकता।

समस्या

DOM एक डबल-लिंक्ड ट्री है। एक नोड का रेफरेंस पूरे ट्री को गार्बेज कलेक्शन से रोकता है।

उदाहरण: मेमोरी लीक पैदा करना

<html> <body> <script>
  // DOM एलिमेंट बनाएं
  var element = document.createElement("p");
  element.id = "someText";
  document.body.appendChild(element);
  
  // ग्लोबल ऑब्जेक्ट में रेफरेंस स्टोर करें
  var value = {
    text: document.getElementById('someText')
  };
  
  function createFun() {
    value.text.innerHTML = "JavaScript is not Java";
  }
  
  function deleteFun() {
    document.body.removeChild(document.getElementById('someText'));
    // एलिमेंट DOM से हट गया लेकिन 'value.text' अभी भी रेफरेंस रखता है!
  }
  
  createFun();
  deleteFun();
  // 'someText' अभी भी मेमोरी में है क्योंकि 'value.text' इसे रेफर करता है
</script> </body> </html>

क्यों लीक होता है?

  1. एलिमेंट DOM ट्री में जोड़ा गया
  2. ग्लोबल ऑब्जेक्ट value में इसका रेफरेंस स्टोर किया
  3. DOM से हटाया गया लेकिन value.text रेफरेंस बरकरार
  4. गार्बेज कलेक्टर देखता है: रेफरेंस मौजूद है → साफ नहीं करता
  5. पूरा DOM सबट्री मेमोरी में रहता है

समाधान: मेमोरी लीक रोकना

बेस्ट प्रैक्टिस: वेरिएबल को इवेंट लिस्टनर/स्कोप के अंदर लोकल रखें।

<script>
  function setup() {
    // लोकल वेरिएबल - फंक्शन खत्म होने पर रेफरेंस खत्म
    var element = document.createElement("p");
    element.id = "someText";
    document.body.appendChild(element);
    
    var value = { text: element };  // लोकल रेफरेंस
    
    function createFun() {
      value.text.innerHTML = "JavaScript is not Java";
    }
    
    function deleteFun() {
      document.body.removeChild(element);
      // फंक्शन खत्म होने पर 'element' और 'value' स्कोप से बाहर
      // → गार्बेज कलेक्टर साफ कर सकता है
    }
    
    createFun();
    deleteFun();
  }
  
  setup();  // कॉल करने के बाद क्लीनअप अपने आप
</script>

अन्य समाधान

  • element = null सेट करके रेफरेंस तोड़ें
  • WeakMap/WeakRef उपयोग करें (कैश के लिए)
  • इवेंट लिस्टनर्स हटाएं: element.removeEventListener()
  • क्लोजर्स में सावधानी से रेफरेंस रखें

डेवलपर टूल्स में डिटेक्शन

  1. Chrome DevTools → Memory टैब
  2. Heap snapshot लें
  3. "Detached" फिल्टर करें
  4. रेफरेंस चेन देखें: कौन सा JS ऑब्जेक्ट होल्ड कर रहा है
  1. JavaScript DOM क्या है? - पूर्ण गाइड JavaScript DOM क्या है? - पूर्ण गाइड

    JavaScript डॉक्यूमेंट ऑब्जेक्ट मॉडल (DOM) एक वेबपेज के HTML एलिमेंट्स का प्रतिनिधित्व है। यह एक इंटरफेस है जिसका उपयोग हम वेब पेज को उसकी सामग्री या शैली को बदलकर मैनिपुलेट करने के लिए कर सकते हैं। हम किसी वेबपेज पर राइट क्लिक करके और inspect चुनकर DOM को एक्सेस कर सकते हैं। ऐसा करने से, एक सेक्शन

  1. Internet Explorer में JavaScript कैसे डीबग करें? Internet Explorer में JavaScript कैसे डीबग करें?

    त्रुटियों को ट्रैक करने का सबसे बुनियादी तरीका है अपने ब्राउज़र में त्रुटि जानकारी चालू करना। डिफ़ॉल्ट रूप से, Internet Explorer पृष्ठ पर त्रुटि होने पर स्टेटस बार में एक त्रुटि आइकन दिखाता है। इस आइकन पर डबल-क्लिक करने से विशिष्ट त्रुटि के बारे में जानकारी दिखाने वाला एक डायलॉग बॉक्स खुलता है। चूं

  1. JavaScript में बटन क्लिक पर li एलिमेंट्स कैसे हटाएं? JavaScript में बटन क्लिक पर li एलिमेंट्स कैसे हटाएं?

    प्रत्येक <li> में बटन जोड़ें, इवेंट डेलिगेशन या व्यक्तिगत लिसनर से remove() या closest() मेथड से पैरेंट <li> हटाएं। HTML स्ट्रक्चर <ul id=subjectList> <li class=subjectName>JavaScript <button class=removeBtn>हटाएं</button></li> <li class=subjectN