2012-12-28 9 views
6

मैं एक आवेदन जहाँ मैं क्रमिक रूप से एक सर्वर से एमपी 3 फ़ाइलों को डाउनलोड कर रहा हूँ है के बाहर आवंटित करने के लिए, अस्थायी रूप से अपने सर्वर में उन्हें भंडारण उन्हें ग्राहकों के लिए सीधे स्ट्रीमिंग तो, है, तो तरह मुक्त कर रहे हैं:NodeJS: कैसे बफ़र्स कि वी 8 स्मृति ढेर

function downloadNextTrack(){ 
    var request = http.get('http://mp3server.com', function(response){ 
    response.on('data', function(data) { 
     fs.appendFile('sometrack.mp3', data, function (err) {}); 
    }); 
    response.on('end', function(){ 
     streamTrack('sometrack.mp3'); 
    } 
    }); 
}; 

var clients = []; // client response objects are pushed to this array when they request the stream through a route like /stream.mp3 

var stream; 

function streamTrack(track){ 
    stream = fs.createReadStream(track); 
    stream.on('data', function(data){ 
    clients.forEach(function(client) { 
     client.write(data); 
    }); 
    }); 
    stream.on('end', function(){ 
    downloadNextTrack(); // redoes the same thing with another track 
    } 
}; 

जाहिर है इस कोड, बफ़र्स जो ओएस द्वारा मुक्त नहीं किया जा रहा है की एक बहुत कुछ पैदा कर रही है जब मैं 'मुक्त -M' कमांड चलाने के लिए, यह मैं (एप्लिकेशन चलाने का लगभग 4 घंटे के बाद प्राप्त होता है):

    total  used  free  shared buffers  cached 
       Mem: 750  675   75   0   12  180 
-/+ buffers/cache:   481  269 
      Swap: 255  112  143 

'बफर' के तहत संख्या लगातार बढ़ती है (साथ ही साथ कैच एड मेमोरी) और ओएस स्पष्ट रूप से उस 180 एमबी को पुनः प्राप्त नहीं करता है, जब तक कि मेरा ऐप स्मृति और क्रैश से बाहर हो जाता है जब मैं ट्रैक की बिटरेट, नमूना दर, आईडी 3 जानकारी इत्यादि को सत्यापित करने के लिए एक छोटी सी प्रक्रिया को बढ़ाने की कोशिश करता हूं।

मैं अलग-अलग टूल पता लगाने के लिए अगर यह एक आंतरिक स्मृति रिसाव था और यह नहीं है (जैसे memwatch और nodetime के रूप में) का एक बहुत के साथ का निदान किया है, वी 8 स्मृति ढेर के साथ-साथ नोड आरएसएस भिन्न हो +/- 10 एमबी लेकिन लगातार रहने अधिकांश भाग के लिए जबकि ओएस फ्री मेमोरी कम हो जाती है और कम होती है (जब नोड प्रक्रिया शुरू होती है तो मेरे पास 350 एमबी मुफ्त मेमोरी होती है)।

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

पी एस। मैं उबंटू 10.04 पर नोड v0.8.16 चला रहा हूं।

+1

हाय, हो सकता है यह एक बेवकूफ सवाल है, लेकिन, मुझे ठीक कर लें मैं गलत हूँ: आदेश 0) डाउनलोड ट्रैक # है 0 1) जब खत्म, सभी cliends 2) जब खत्म धारा, dwonload के लिए धारा # 1 ट्रैक जब आप ऐसा करते हैं यह प्रत्यावर्तन की तरह, सही है? पहली कॉल 'streamTrack' के अंदर आप एक धारा चर राशि (यह एक वैश्विक चर रहा है?) और, अंत में, आप 'downloadNextTrack' कहते हैं और एक अन्य धारा चर के साथ, फिर 'streamTrack' कहते हैं। यदि आप रिकर्सन का उपयोग करते हैं तो यह समस्या का स्रोत हो सकता है? –

+0

उत्पादन कोड में यह स्ट्रीम चर एक सिंगलटन की तरह काम करता है, इसलिए जब कोई और स्ट्रीम शुरू होती है, तो इसे नए रीडस्ट्रीम पर फिर से सौंप दिया जाता है। यह एक वैश्विक चर की तरह काम करता है लेकिन यह वैश्विक वैरिएबल प्रति से नहीं है। – pedromtavares

+0

'सेटटाइमआउट (फ़ंक्शन() {स्ट्रीमट्रैक (' somefile ');}, 0); 'का उपयोग करने का प्रयास करें। यह "रिकर्सिविटी" त्रुटि को मार देगा (मुझे पता है, थोड़ा विलंबित उत्तर) –

उत्तर

2

मैं टियागो, से सहमत हूं, मुझे लगता है कि यह आपके कोड की पुनरावर्ती प्रकृति के कारण होता है। मैं धाराओं में नहीं सोचता क्या, अपने ढेर ऊपर gobbling क्योंकि जैसा कि आपने कहा, धारा चर हर यात्रा के साथ एक नया ReadStream साथ पुन: सौंपा जा रहा है। हालांकि, http.get के अनुरोध और प्रतिक्रिया (और जो कुछ बफ़र वे का उपयोग करें) पंक्ति 2 में अगले चरण कॉल करने से पहले जारी किया जा रहा कभी नहीं कर रहे हैं; वे DownloadNextTrack फ़ंक्शन के भीतर स्कॉप्ड हैं। आप एक रिकर्सिव स्टैक ट्रेस के साथ समाप्त होते हैं जिसमें प्रति फ़ाइल अनुरोध और प्रतिक्रिया ऑब्जेक्ट्स (और कुछ अंतर्निहित बफर) का एक सेट होता है।

सामान्य रूप से, यदि इस कोड को कई बार चलाने की ज़रूरत है, तो कई बार रिकर्सन का चयन क्यों न करें और इसे पूरी तरह से करें? एक प्रोग्राम समाप्त होने तक, कभी भी समाप्त होने वाली पुनरावृत्ति हमेशा अधिक से अधिक स्मृति को घुमाएगी, भले ही आपके हिस्से पर कोई स्मृति रिसाव न हो।

+0

तो क्या आप StreamTrack को कॉल करने से पहले अनुरोध और प्रतिक्रिया चर को रद्द करने का सुझाव देते हैं? मैंने सोचा कि एक बार प्रतिक्रिया समाप्त हो जाने के बाद और मैं उन चर का उपयोग नहीं कर रहा था, वे अंततः जीसी द्वारा एकत्रित हो जाएंगे। सबकुछ एक अनंत लूप में रखेगा इसे हल करें? एफवाईआई: यह उत्पादन कोड है: https://github.com/pedromtavares/radio/blob/master/lib/provider.js – pedromtavares

+0

नलिंग मदद नहीं करेगा, क्योंकि स्टैक ट्रेस बढ़ता है और बढ़ता है और जेएस अभी भी [बंद] रखेगा धारा वस्तुओं के संदर्भ। अनंत लूप का उपयोग करना (एक साधारण पुनरावृत्ति लूप) चाल करेगा, क्योंकि तब पुरानी स्ट्रीम ऑब्जेक्ट्स का संदर्भ देगा। –

+0

कुछ सोचने के बाद, विचार की आपकी रेखा वास्तव में समझ में आती है। मेरे पास अभी कोड को दोबारा करने का समय नहीं है (और मेरे पास इसके लिए परीक्षण नहीं हैं, मुझ पर शर्म आती है) यह देखने के लिए कि क्या यह वास्तव में समस्या को ठीक करेगा, लेकिन मैं आपके उत्तर को सही मानता हूं। धन्यवाद आदमी :) – pedromtavares

0

इस पढ़ें: http://www.linuxatemyram.com

बफर कैश inodes और dentries (फाइल सिस्टम संरचनाओं) के लिए एक कैश है। वह स्मृति अभी भी प्रक्रियाओं के लिए उपलब्ध है। आपको इसकी परवाह नहीं करनी चाहिए।

+1

हालांकि यह लिंक प्रश्न का उत्तर दे सकता है, लेकिन यहां उत्तर के आवश्यक हिस्सों को शामिल करना बेहतर है और संदर्भ के लिए लिंक प्रदान करना बेहतर है। लिंक किए गए पृष्ठ में परिवर्तन होने पर लिंक-केवल उत्तर अमान्य हो सकते हैं। - [समीक्षा से] (/ समीक्षा/कम गुणवत्ता वाली पोस्ट/11470551) –

+0

ठीक है, यह सिर्फ इतना है कि अंग्रेजी मेरी पहली भाषा नहीं है और यह साइट इसे बेहतर तरीके से समझाती है। यह भी नहीं पता कि उनकी सामग्री की प्रतिलिपि बनाना और चिपकाना उचित उपयोग है या नहीं। फिर, उस साइट का एकमात्र उद्देश्य उस चीज़ को समझाना है। – arboreal84

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