डिटैच्ड 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>
क्यों लीक होता है?
- एलिमेंट DOM ट्री में जोड़ा गया
- ग्लोबल ऑब्जेक्ट
valueमें इसका रेफरेंस स्टोर किया - DOM से हटाया गया लेकिन
value.textरेफरेंस बरकरार - गार्बेज कलेक्टर देखता है: रेफरेंस मौजूद है → साफ नहीं करता
- पूरा 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() - क्लोजर्स में सावधानी से रेफरेंस रखें
डेवलपर टूल्स में डिटेक्शन
- Chrome DevTools → Memory टैब
- Heap snapshot लें
- "Detached" फिल्टर करें
- रेफरेंस चेन देखें: कौन सा JS ऑब्जेक्ट होल्ड कर रहा है