2012-01-11 7 views
14

नोडजेएस में मेमोरी लीक डीबग करने की कोशिश में, मुझे यह काफी मुश्किल लगता है (प्रोफाइलिंग टूल की कमी के कारण मुझे पता है)।नोड.जेएस में बंद होने के उदाहरण जो मेमोरी लीक का कारण बनेंगे

मैंने सोचा कि मैं मूल बातें वापस जाऊंगा और सुनिश्चित करूँगा कि मैं समझता हूं कि विशेष रूप से नोडजेएस में मेमोरी रिसाव कैसे बनाया जाएगा। मैं बंद होने के प्रकारों के बारे में उलझन में हूं जो स्मृति रिसाव का कारण बन सकता है और उस स्मृति को मुक्त करने के लिए कचरा कलेक्टर की आवश्यकता के बारे में अनिश्चित हूं।

क्या आप मुझे बुनियादी पैटर्न के कुछ उदाहरण दे सकते हैं जो Node.js में मेमोरी रिसाव का कारण बनेंगे?

उत्तर

17

बिल्कुल "रिसाव" नहीं है, लेकिन यह एक आम नुकसान हो सकता है।

var fn = (function() { 
    var a = "super long string ..."; 
    var b = "useless value"; 
    var c = "Hello, World!"; 

    return function() { 
    return c; 
    }; 
})(); 

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


इसे कैसे ठीक करें?

सरल विकल्प उन चरों को रद्द करना है जिन्हें आप अपने फ़ंक्शन के अंत में परवाह नहीं करते हैं। चर अभी भी दायरे में हैं, लेकिन उनका डेटा जारी किया जाएगा। इसलिए उनके कार्यक्षेत्र जारी किया जा सकता

var fn = (function() { 
    var a = "super long string ..."; 
    var b = "useless value"; 
    var c = "Hello, World!"; 

    // do stuff with a and b 

    a = b = null; 

    return function() { 
    return c; 
    }; 
})(); 

या आप कुछ भी अस्थायी का उपयोग करता है को तोड़ सकते थे उसके अपने समारोह में वार्स। यह एक बड़ी परियोजना के लिए एक बेहतर समाधान है।

var doSetup = function() { 
    var a = "super long string ..."; 
    var b = "useless value"; 
    // do stuff with a and b 
}; 

var fn = (function() { 
    doSetup(); 

    var c = "Hello, World!"; 

    return function() { 
    return c; 
    }; 
})(); 
+0

क्या यह वापस नहीं किया था अगर ग लेकिन इस तरह यह करने के लिए संदर्भ बनाया: 'वर fn = (function() { वर एक =" सुपर लंबी स्ट्रिंग ... "; वर ख =" बेकार मूल्य " ; var c = "हैलो, वर्ल्ड!"; फ़ंक्शन() { सी = "कुछ और"; }; })(); ' – crickeys

+0

बिंदु यह है कि यदि फ़ंक्शन अभी भी संदर्भित है, तो इसे बनाए गए क्लोजर स्कोप को स्मृति में रखा जाता है। वास्तव में वह कार्य क्या करता है उस तथ्य पर कोई प्रभाव नहीं पड़ता है। –

+0

तो, आप यह सुनिश्चित करने के लिए पोस्ट किए गए मूल कोड को कैसे ठीक करेंगे, यह अब और लीक नहीं कर रहा था? – crickeys

-1

से: http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml?showone=Closures#Closures

एक बात ध्यान में रखना है, तथापि, कि एक बंद इसका आवरण गुंजाइश के लिए एक सूचक रखता है। नतीजतन, एक डीओएम तत्व को बंद करने से एक गोलाकार संदर्भ बना सकता है और इस प्रकार, एक स्मृति रिसाव। उदाहरण के लिए, निम्न कोड में:

function foo(element, a, b) { 
    element.onclick = function() { /* uses a and b */ }; 
} 

समारोह बंद तत्व के लिए संदर्भ रहता है, एक, और ख भले ही यह कभी नहीं तत्व का उपयोग करता। चूंकि तत्व बंद होने का संदर्भ भी रखता है, हमारे पास एक चक्र है जिसे कचरा संग्रह द्वारा साफ नहीं किया जाएगा।

function foo(element, a, b) { 
    element.onclick = bar(a, b); 
} 

function bar(a, b) { 
    return function() { /* uses a and b */ } 
} 
+1

कुछ हद तक सहायक है, लेकिन मुझे डोम तत्वों के साथ कुछ भी दिलचस्पी नहीं है क्योंकि यह नोड है। जेएस – crickeys

0
  1. आप Chrome देव उपकरणों के साथ डिबग नोड क्षुधा को नोड निरीक्षक का उपयोग कर सकते हैं: इन स्थितियों में, इस प्रकार कोड संरचित किया जा सकता।

  2. अप्रयुक्त बंद चर के बारे में स्वीकार्य उत्तर गलत है क्योंकि आधुनिक जेएस इंजनों में, वास्तव में आंतरिक चर में संदर्भित उन चरों को बंद करने के दायरे में शामिल किया गया है। शेष स्वचालित रूप से कचरा इकट्ठा होते हैं। दूसरे शब्दों में, यह सैद्धांतिक स्थिति वास्तव में नोड में कभी नहीं होगी।

  3. एक्सप्रेस का उपयोग कर एक वास्तविक (और काफी आम) उदाहरण के लिए, आप मिडलवेयर बना सकते हैं जो फ़ाइल को प्रत्येक अनुरोध के लिए स्मृति में लोड करता है और फिर उसी अनुरोध में एक अनचाहे अपवाद फेंक देता है, फेंक दिया अपवाद पकड़ता है, और फिर विफल रहता है प्रक्रिया से बाहर निकलें।

फेंक दिया अपवाद अनुरोधित अनुरोध संसाधनों को अनुरोध/प्रतिक्रिया चक्र के अंत में साफ होने के बजाय रुकने का कारण बनता है।

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

यह स्पष्ट रूप से उपयोगकर्ता अनुभव पर नकारात्मक प्रभाव डालता है।

Why Would an Exception Cause Resource Leaks in Node.js भी देखें।

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