2013-04-27 11 views
13

मैं समझना चाहता हूं कि किस प्रकार का कोड जावास्क्रिप्ट में मेमोरी लीक का कारण बनता है और नीचे लिपि बनाता है। हालांकि, जब मैं ओएस एक्स पर सफारी 6.0.4 में स्क्रिप्ट चलाता हूं तो गतिविधि मॉनीटर में दिखाए गए मेमोरी खपत में वास्तव में वृद्धि नहीं होती है।मैं जावास्क्रिप्ट में मेमोरी रिसाव कैसे बना सकता हूं?

क्या मेरी स्क्रिप्ट के साथ कुछ गलत है या यह अब आधुनिक ब्राउज़र के साथ कोई समस्या नहीं है? http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml?showone=Closures#Closures

संपादित करें: बग की वजह से लीक करने के लिए ऊपर दिए गए कोड को जाहिरा तौर पर किया गया है तय: http://jibbering.com/faq/notes/closures/#clMem

लेकिन मेरे

<html> 
<body> 
</body> 
<script> 
var i, el; 

function attachAlert(element) { 
    element.onclick = function() { alert(element.innerHTML); }; 
} 

for (i = 0; i < 1000000; i++) { 
    el = document.createElement('div'); 
    el.innerHTML = i; 
    attachAlert(el); 
} 
</script> 
</html> 

स्क्रिप्ट गूगल के जावास्क्रिप्ट स्टाइल गाइड के बंद खंड पर आधारित है सवाल बनी हुई है: क्या कोई जावास्क्रिप्ट कोड का यथार्थवादी उदाहरण प्रदान करने में सक्षम होगा जो आधुनिक ब्राउज़रों में स्मृति को रिसाव करता है?

इंटरनेट पर कई लेख हैं जो सुझाव देते हैं कि मेमोरी लीक जटिल एकल पृष्ठ अनुप्रयोगों के लिए एक मुद्दा हो सकता है लेकिन मुझे अपने ब्राउज़र में एक उदाहरण खोजने में कठिनाई हो रही है।

उत्तर

5

आप जिस तत्व को आपने बनाया है उसे कहीं भी नहीं रखा है और कहीं भी संदर्भित किया गया है - यही कारण है कि आप स्मृति उपयोग में वृद्धि नहीं देख रहे हैं। तत्व को डीओएम में संलग्न करने का प्रयास करें, या किसी ऑब्जेक्ट में इसे स्टोर करें, या ऑनक्लिक को एक अलग तत्व बनें जो चारों ओर चिपक जाती है। फिर आप स्मृति उपयोग skyrocket देखेंगे। कचरा कलेक्टर कुछ भी आ जाएगा और साफ कर देगा जिसे अब संदर्भित नहीं किया जा सकता है।

मूल रूप से

अपने कोड का एक पूर्वाभ्यास:

  • तत्व (एल)
  • एक नया समारोह है कि तत्व
  • समारोह सेट कि उस तत्व की onclick होने के लिए संदर्भ बनाने बनाने
  • तत्व को एक नए तत्व के साथ ओवरराइट करें

सब कुछ केंद्रित है तत्व मौजूद है। एक बार तत्व तक पहुंचने का कोई तरीका नहीं है, तो ऑनक्लिक अब और नहीं पहुंचा जा सकता है। इसलिए, चूंकि ऑनक्लिक तक पहुंचा नहीं जा सकता है, इसलिए बनाया गया फ़ंक्शन नष्ट हो गया है .. और फ़ंक्शन के पास तत्व का एकमात्र संदर्भ था .. इसलिए तत्व भी साफ हो गया है।

किसी के पास एक और तकनीकी उदाहरण हो सकता है, लेकिन यह जावास्क्रिप्ट कचरा कलेक्टर की मेरी समझ का आधार है।

संपादित करें:,

<html> 
<body> 
</body> 
<script> 
var i, el; 

var createdElements = {}; 
var events = []; 

function attachAlert(element) { 
    element.onclick = function() { alert(element.innerHTML); }; 
} 

function reallyBadAttachAlert(element) { 
    return function() { alert(element.innerHTML); }; 
} 

for (i = 0; i < 1000000; i++) { 
    el = document.createElement('div'); 
    el.innerHTML = i; 

    /** posibility one: you're storing the element somewhere **/ 
    attachAlert(el); 
    createdElements['div' + i] = el; 

    /** posibility two: you're storing the callbacks somewhere **/ 
    event = reallyBadAttachAlert(el); 
    events.push(event); 
    el.onclick = event; 

} 
</script> 
</html> 

तो, # 1 के लिए आप बस कहीं उस तत्व के लिए एक संदर्भ के भंडारण कर रहे हैं: यहाँ आपकी स्क्रिप्ट के लीक संस्करण के लिए कई संभावनाएं से एक है। इससे कोई फर्क नहीं पड़ता कि आप इसका कभी भी उपयोग नहीं करेंगे - क्योंकि उस संदर्भ को ऑब्जेक्ट में बनाया गया है, तत्व और इसकी कॉलबैक कभी नहीं चलेगी (या कम से कम जब तक आप ऑब्जेक्ट से तत्व को हटा नहीं देते)। संभावना # 2 के लिए, आप कहीं भी घटनाओं को संग्रहित कर सकते हैं। क्योंकि ईवेंट तक पहुंचा जा सकता है (यानी events[10](); कर रहा है) भले ही तत्व कहीं भी नहीं मिला है, फिर भी यह घटना द्वारा संदर्भित है .. इसलिए तत्व सरणी से हटाए जाने तक स्मृति और ईवेंट में भी रहेगा।

+0

आपके उत्तर के लिए धन्यवाद! क्या आप चित्रण के लिए मेरी स्क्रिप्ट का एक संशोधित संस्करण पोस्ट कर पाएंगे? – user2327642

+0

हो गया। उम्मीद है कि मदद करता है। – Stephen

+0

धन्यवाद, लेकिन मुझे नहीं लगता कि यह एक प्रासंगिक उदाहरण है। यदि मैं बनाए गए सभी तत्वों के संदर्भ संग्रहीत करता हूं तो मुझे उम्मीद नहीं है कि उन्हें कचरा इकट्ठा किया जाए। मेरे कोड का बिंदु यह है कि बंद करने के लिए एक परिपत्र संदर्भ बनाता है। सर्कुलर संदर्भ आमतौर पर कचरा कलेक्टर के लिए कोई समस्या नहीं है, लेकिन जैसा कि मैंने अब सीखा - वहां एक बग था जहां कचरा संग्रह कुछ ब्राउज़रों में काम नहीं करेगा जब परिपत्र संदर्भ में शामिल वस्तुओं में से एक एक डीओएम तत्व था। – user2327642

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