2015-02-04 9 views
6

ट्रिगर नहीं लग रहा है क्योंकि मैं उलझन में हूं क्योंकि मेरा एप्लिकेशन स्मृति को लीक कर रहा है। यह एक टीसीपी सर्वर है जो प्रति मिनट सैकड़ों पैकेट प्रोसेस करता है। मैंने कोड की जांच की है, इसे सुधार लिया है और स्मृति को प्रोफाइल किया है।node.js v8 कचरा संग्रह

सब कुछ ठीक लगता है, कम यातायात के साथ स्थानीय रूप से परीक्षण वास्तव में दिखाता है कि जीसी स्मृति को ठीक से रिलीज़ करता है। लेकिन जब लाइव भारी यातायात सर्वर पर यह नहीं करता है।

तो मैंने expose-gc विकल्प का उपयोग करने की कोशिश की और प्रत्येक डिस्कनेक्शन के लिए जबरन जीसी जोड़ा और अब मुझे पता चला कि स्मृति अब लीक नहीं हो रही है या यह सब भी लीक हो रही है?

तो, मेरा निष्कर्ष यह है कि जीसी सक्रिय नहीं हुआ है। मेरे सर्वर में 3 जीबी मेमोरी है और कुछ ही घंटों में आवेदन 2.8 जीबी खाने के लिए मिलता है।

अब जबरन जीसी के साथ आवेदन अब लीक नहीं हो रहा है। यह लगभग 200 एमबी मेमोरी बनाए रखता है।

तो, मेरा सवाल, जीसी क्यों ट्रिगर नहीं हो रहा था?

+0

क्या आपको कभी समाधान मिला है? मुझे एक ही समस्या है T_T –

+1

@MarsZhu क्षमा करें, मैंने नोड पर छोड़ दिया, और इसके बजाय गो का इस्तेमाल किया, सबसे अच्छा निर्णय। – majidarif

उत्तर

1

Source: StrongLoop Blog

बुनियादी समस्या कचरा संग्रहण को हल करती है मृत स्मृति क्षेत्रों (पहुंच योग्य वस्तुओं/कचरा), जो एक वस्तु जो लाइव है से पहुंचा जा सकता संकेत के कुछ श्रृंखला के माध्यम से नहीं कर रहे हैं की पहचान है। एक बार जब पहचान, इन क्षेत्रों नया आवंटन या ऑपरेटिंग सिस्टम

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

तो आपके कोड onSuccess विधि में आपके अनुरोध ऑब्जेक्ट द्वारा संदर्भित किया जाएगा। हालांकि, onSuccess केवल एक ही फ़ंक्शन है जिसे सभी अनुरोध ऑब्जेक्ट्स के लिए श्रोता के रूप में पुन: उपयोग किया जा रहा है ताकि स्मृति मेमोरी का नेतृत्व न हो।

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

वस्तुओं जो दो नाबालिग कचरा संग्रह बच गया है को "पुराने अंतरिक्ष।" प्रचार किया जाता है पुराने अंतरिक्ष कचरा भरा जीसी (प्रमुख कचरा संग्रहण चक्र) है, जो कम हो जाते है में एकत्र है। मुझे लगता है कि यह बहुत दूर है, लेकिन चक्रों को साफ़ करने से तेज़ी से आवंटित करने का विकल्प माना जा सकता है, और इस प्रकार जब आप कचरा संग्रह मैन्युअल रूप से ट्रिगर करते हैं, तो एक पूर्ण जीसी चक्र ट्रिगर होता है।

तेज वस्तु आवंटन, लघु कचरा संग्रहण रुक जाता है, और "कोई स्मृति विखंडन वी 8" एक रोकने के दुनिया को रोजगार, पीढ़ीगत, सटीक, कचरा कलेक्टर सुनिश्चित करने के लिए। पूर्ण कचरा संग्रहण चक्र करते समय V8 अनिवार्य रूप से प्रोग्राम निष्पादन रोकता है।

यह समझा सकता है कि वी 8 को कचरा सफाई में मजबूर होने पर स्मृति क्यों रिसाव नहीं होती है।

+2

यह भ्रमित है कि [strongloops] (http://strongloop.com/strongblog/node-js-performance-garbage-collection/) ब्लॉग से सटीक पैराग्राफ लेने का उल्लेख न करें। – majidarif

+0

सच है, मैं स्रोत जोड़ने के लिए क्षमा चाहता हूं। मैं आमतौर पर ऐसा करता हूं। – Selfish

+0

इस उत्तर का केवल अंतिम पैरा प्रश्न के लिए प्रासंगिक है! "ऑब्जेक्ट्स जो दो मामूली कचरा संग्रह से बच गए हैं उन्हें" पुरानी जगह "में बढ़ावा दिया जाता है। पुरानी जगह पूरी जीसी (प्रमुख कचरा संग्रहण चक्र) में कचरा इकट्ठा किया जाता है, जो बहुत कम होता है। मुझे लगता है कि यह बहुत दूर है, लेकिन विकल्प आप को व्यापक चक्रों से तेज़ी से आवंटित करने पर विचार किया जा सकता है, और इस प्रकार जब आप कचरा संग्रहण मैन्युअल रूप से ट्रिगर करते हैं, तो एक पूर्ण जीसी चक्र ट्रिगर होता है। " –

0

मैं कचरा संग्रह के साथ एक ही समस्या को देख रहा हूं। एक टेस्ट स्क्रिप्ट मेमोरी में बार-बार एक ही सामग्री (प्रतिक्रिया द्वारा प्रस्तुत) को खत्म करने के लिए मेरे सर्वर का परीक्षण करना एक घंटे या उससे भी अधिक समय में समाप्त हो जाएगा। इस एडब्ल्यूएस इंस्टेंस में केवल 1 जीबी रैम है।

जब भी हेपयूड 256 एमबी से अधिक हो जाता है तो कचरा संग्रह को मजबूर करने के बाद सब कुछ अंत में घंटों तक ठीक काम करता है। एक जीसी के बाद 256 एमबी से थोड़ा अधिक 150 एमबी से ढेर सारे ढेर।

इस बीच हीपटॉटल अंततः लगभग 340 एमबी स्थिर हो जाता है।

मेरा निष्कर्ष यह है कि मेरा सर्वर स्मृति को रिसाव नहीं करता है, कचरा संग्रह अपेक्षित के रूप में नहीं हो रहा है।

setInterval (function() { 
    let mu = process.memoryUsage(); 
    console.log('heapTotal:', mu.heapTotal, 'heapUsed:', mu.heapUsed); 
    if (mu.heapUsed > 256 * 1024 * 1024) { 
     console.log('Taking out the garbage'); 
     global.gc(); 
    } 
}, 1000 * 60); 

यह शायद बेहतर हो हर अनुरोध के बाद स्मृति जाँच करने के लिए होगा:

यहाँ मैं क्या कर रहा है।

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