2012-01-13 15 views
8

मैं निम्नलिखित कोड के साथ एक स्मृति रिसाव दिखाई दे रही है:node.js फ़ाइल मेमोरी लीक?

while (true) { 
    console.log("Testing."); 
} 

मैं स्ट्रिंग को परिभाषित करने और सिर्फ एक निरंतर उपयोग करने की कोशिश की है, लेकिन यह स्मृति, अभी भी लीक:

var test = "Testing."; 
while (true) { 
    console.log(test); 
} 

ही रिसाव अगर मैं मानक लॉग के बजाय एक फ़ाइल का उपयोग होता है:

var test = "Testing."; 
var fh = fs.createWriteStream("test.out", {flags: "a"}); 
while (true) { 
    fh.write(test); 
} 

मैं शायद सोचा था कि यह था, क्योंकि मैं ठीक से फ़ाइल को बंद करने नहीं था, लेकिन मैं इस और एस करने की कोशिश की जब तक रिसाव देखा:

var test = "Testing"; 
while (true) { 
    var fh = fs.createWriteStream("test.out", {flags: "a"}); 
    fh.end(test); 
    fh.destroy(); 
    fh = null; 
} 

किसी को भी मैं कैसे स्मृति लीक बिना बातें लिखने के लिए माना जाता रहा हूँ के बारे में कोई संकेत है?

उत्तर

10

ऐसा इसलिए होता है क्योंकि आप कभी भी "सफल" घटनाओं को संभालने का मौका नहीं देते हैं, इसलिए वे अंतहीन रूप से कतारबद्ध होते हैं। नोड को उन्हें संभालने का मौका देने के लिए, आपको ईवेंट लूप को समय-समय पर एक पुनरावृत्ति करना होगा। यह लीक नहीं होगा: क्योंकि आप लगभग एक बार है कि इस मामले को पर डेटा की इतनी भारी मात्रा में लिखने के लिए की आवश्यकता नहीं है

function newLine() { 
    console.log("Testing."); 
    process.nextTick(newLine); 
} 
newLine(); 

वास्तविक उपयोग मामलों में, यह कोई समस्या नहीं है। और यदि ऐसा होता है, तो ईवेंट लूप को समय-समय पर चक्र दें।

हालांकि, इसके साथ एक दूसरा मुद्दा भी है जो nextTick चाल के साथ भी होता है: लेखन एसिंक है, और यदि कंसोल/फ़ाइल/जो भी नोड से धीमी है, तो नोड बफर डेटा को अंतहीन रूप से तब तक मुक्त कर देता है जब तक आउटपुट फिर से मुक्त न हो जाए। इससे बचने के लिए, आपको कुछ सामान लिखने के बाद drain ईवेंट सुनना होगा - यह आपको बताता है कि पाइप फिर से मुक्त हो जाती है। यहां देखें: http://nodejs.org/docs/latest/api/streams.html#event_drain_

+0

मैं आपके समाधान को फ़ाइल हैंडलर ('fs.createWriteStream') के साथ पुन: उत्पन्न करने में सक्षम था, लेकिन अगर मैं' console.log' के साथ प्रयास करता हूं, तो मुझे अभी भी स्मृति रिसाव मिलती है। 'फ़ंक्शन लिखें कंसोल() {console.log ("test"); अगर (टाइपोफ (जीसी) == "फ़ंक्शन") जीसी(); process.nextTick (writeConsole); } लिखें कंसोल(); ' उपरोक्त कोड ब्लॉक को 'नोड test.js' के साथ चलाते समय, मैं प्रत्येक पुनरावृत्ति के साथ अपना मेमोरी उपयोग गुब्बारा देखता हूं। जब मैं इसे 'नोड - एक्सपोज़-जीसी test.js' के रूप में चलाता हूं, तो मुझे कोई निरंतर वृद्धि दिखाई नहीं देती है। – facetious

+0

@ फैसीटियस: यह अक्सर जीसी चक्र नहीं करता है, जो अक्षम होगा। इसे थोड़ी देर के लिए चलाएं, और आप देखेंगे कि स्मृति उपयोग अंततः प्रारंभ स्तर तक गिर जाता है। – thejh

+0

@ फैसीटियस: मुझे अपने आप के साथ प्रयोग करना भी याद है - मैंने gnuplot के साथ मेमोरी उपयोग ग्राफ बनाया है, और यदि मुझे सही याद है, तो यह हमेशा कुछ समय के लिए और अधिक मिलता है और फिर लगभग प्रारंभ मूल्य पर वापस आ जाता है। – thejh

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