मेमोरी से जुड़ी समस्याएं ठीक करना

कायस बास्क
कायस बैस्क

पेज की परफ़ॉर्मेंस पर असर डालने वाली मेमोरी से जुड़ी समस्याओं का पता लगाने के लिए, Chrome और DevTools का इस्तेमाल करने का तरीका जानें. इन समस्याओं में, मेमोरी लीक, मेमोरी का फूलना, और बार-बार कूड़ा संग्रह करने जैसी समस्याएं शामिल हैं.

खास जानकारी

  • Chrome टास्क मैनेजर की मदद से, पता लगाएं कि आपका पेज फ़िलहाल कितनी मेमोरी का इस्तेमाल कर रहा है.
  • टाइमलाइन रिकॉर्डिंग की मदद से, यह समझें कि समय के साथ मेमोरी में कितनी जगह इस्तेमाल हुई.
  • हीप स्नैपशॉट की मदद से, डिटैच किए गए डीओएम ट्री (मेमोरी लीक की एक आम वजह) की पहचान करें.
  • ऐलोकेशन टाइमलाइन रिकॉर्डिंग की मदद से जानें कि आपके JS हीप में नई 'यादें' कब असाइन की जाएंगी.

खास जानकारी

RAIL परफ़ॉर्मेंस मॉडल के हिसाब से, परफ़ॉर्मेंस की आपकी कोशिशों का फ़ोकस आपके उपयोगकर्ता होने चाहिए.

मेमोरी की समस्याएं इसलिए मायने रखती हैं, क्योंकि अक्सर उपयोगकर्ता इन्हें समझ जाते हैं. उपयोगकर्ता मेमोरी से जुड़ी समस्याओं के बारे में इन तरीकों से जान सकते हैं:

  • समय के साथ, पेज की परफ़ॉर्मेंस खराब होती जाती है. यह मेमोरी लीक होने का एक लक्षण हो सकता है. मेमोरी लीक तब होता है, जब पेज में कोई गड़बड़ी होती है और समय के साथ पेज धीरे-धीरे ज़्यादा ज़्यादा मेमोरी का इस्तेमाल करता है.
  • पेज की परफ़ॉर्मेंस लगातार खराब है. यह अक्सर याददाश्त बढ़ने का एक लक्षण है. ज़्यादा मेमोरी का इस्तेमाल तब किया जाता है, जब कोई पेज, पेज की स्पीड को बढ़ाने के लिए ज़रूरत से ज़्यादा मेमोरी का इस्तेमाल करता है.
  • पेज की परफ़ॉर्मेंस में देरी हो रही है या वह बार-बार रुक रहा है. यह शायद बार-बार कचरे के संग्रह का एक लक्षण है. जब ब्राउज़र मेमोरी को फिर से रिकवर करता है, तो उसे ट्रैश कलेक्शन कहा जाता है. ऐसा होने पर ब्राउज़र तय करता है. कलेक्शन के दौरान, सभी स्क्रिप्ट के एक्ज़ीक्यूशन को रोक दिया जाता है. इसलिए, अगर ब्राउज़र बहुत ज़्यादा कचरा इकट्ठा कर रहा है, तो स्क्रिप्ट का एक्ज़ीक्यूशन काफ़ी रुक जाएगा.

बहुत ज़्यादा मेमोरी: "बहुत ज़्यादा" कितनी है?

मेमोरी लीक को आसानी से समझा जा सकता है. अगर कोई साइट धीरे-धीरे ज़्यादा मेमोरी का इस्तेमाल कर रही है, तो इसका मतलब है कि आपके कॉन्टेंट में लीक हो रहा है. हालांकि, याददाश्त के खोने का खतरा कम होता है. "बहुत ज़्यादा मेमोरी का इस्तेमाल करना" किसे माना जाता है?

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

आरएआईएल मॉडल का इस्तेमाल करना और अपने उपयोगकर्ताओं पर ध्यान देना अहम है. पता लगाएं कि आपके उपयोगकर्ताओं के बीच कौनसे डिवाइस लोकप्रिय हैं और फिर उन डिवाइसों पर अपने पेज की जांच करें. अगर उपयोगकर्ताओं का अनुभव लगातार खराब रहा है, तो हो सकता है कि पेज की मेमोरी उन डिवाइसों की मेमोरी को पार कर गई हो.

Chrome टास्क मैनेजर की मदद से, रीयल टाइम में मेमोरी के इस्तेमाल पर नज़र रखें

Chrome टास्क मैनेजर का इस्तेमाल, अपनी मेमोरी से जुड़ी समस्याओं की जांच शुरू करने के लिए करें. टास्क मैनेजर, एक रीयल टाइम मॉनिटर है, जो आपको यह बताता है कि फ़िलहाल कोई पेज कितनी मेमोरी का इस्तेमाल कर रहा है.

  1. टास्क मैनेजर खोलने के लिए, Shift+Esc दबाएं या Chrome के मुख्य मेन्यू में जाएं और ज़्यादा टूल > टास्क मैनेजर को चुनें.

    Task Manager खोलना

  2. 'टास्क मैनेजर' के टेबल हेडर पर राइट क्लिक करें और JavaScript मेमोरी को चालू करें.

    JS मेमोरी चालू करना

ये दो कॉलम आपको इस बारे में अलग-अलग बातें बताते हैं कि आपका पेज मेमोरी का इस्तेमाल कैसे कर रहा है:

  • मेमोरी कॉलम, नेटिव मेमोरी दिखाता है. डीओएम नोड, नेटिव मेमोरी में स्टोर किए जाते हैं. अगर इसकी वैल्यू बढ़ रही है, तो डीओएम नोड बनाए जा रहे हैं.
  • JavaScript मेमोरी कॉलम JS हीप को दिखाता है. इस कॉलम में दो वैल्यू होती हैं. आपकी जिस वैल्यू में दिलचस्पी है वह लाइव नंबर (कोष्ठक में दी गई संख्या) होती है. लाइव नंबर से पता चलता है कि आपके पेज पर मौजूद ऑब्जेक्ट कितनी मेमोरी का इस्तेमाल कर रहे हैं. अगर यह संख्या बढ़ रही है, तो इसका मतलब है कि नए ऑब्जेक्ट बनाए जा रहे हैं या मौजूदा ऑब्जेक्ट बढ़ रहे हैं.

परफ़ॉर्मेंस रिकॉर्डिंग की मदद से, मेमोरी लीक को विज़ुअलाइज़ करना

अपनी जांच की शुरुआत करने के लिए, परफ़ॉर्मेंस पैनल का इस्तेमाल दूसरे पॉइंट के तौर पर भी किया जा सकता है. परफ़ॉर्मेंस पैनल की मदद से, यह देखा जा सकता है कि समय के साथ पेज में कितनी मेमोरी इस्तेमाल हुई है.

  1. DevTools पर परफ़ॉर्मेंस पैनल खोलें.
  2. मेमोरी चेकबॉक्स को चालू करें.
  3. रिकॉर्डिंग करें.

परफ़ॉर्मेंस मेमोरी की रिकॉर्डिंग दिखाने के लिए, नीचे दिया गया कोड देखें:

var x = [];

function grow() {
  for (var i = 0; i < 10000; i++) {
    document.body.appendChild(document.createElement('div'));
  }
  x.push(new Array(1000000).join('x'));
}

document.getElementById('grow').addEventListener('click', grow);

जब भी कोड में रेफ़र किया गया बटन दबाया जाता है, तो दस्तावेज़ के मुख्य हिस्से में दस हज़ार div नोड जुड़ जाते हैं. साथ ही, x कलेक्शन में दस लाख x वर्णों वाली स्ट्रिंग डाली जाती है. इस कोड को चलाने से, नीचे दिए गए स्क्रीनशॉट के जैसी एक टाइमलाइन रिकॉर्डिंग बनती है:

कारोबार को बढ़ाने का आसान उदाहरण

सबसे पहले, यूज़र इंटरफ़ेस की जानकारी. खास जानकारी पैनल में H हम ग्राफ़ (NET के नीचे) JS हीप दिखाता है. खास जानकारी पैनल के नीचे काउंटर पैनल मौजूद होता है. यहां आपको JS हीप (खास जानकारी पैनल में H डिफ़ॉल्ट ग्राफ़) के हिसाब से, मेमोरी के इस्तेमाल का डेटा दिख सकता है. इसमें, दस्तावेज़ों, DOM नोड, लिसनर, और जीपीयू मेमोरी के हिसाब से, मेमोरी के इस्तेमाल की जानकारी भी होती है. चेकबॉक्स को बंद करने से वह ग्राफ़ से छिप जाता है.

अब स्क्रीनशॉट के मुकाबले कोड का विश्लेषण. अगर आप नोड काउंटर (हरे रंग का ग्राफ़) में देखें, तो आपको पता चल जाएगा कि वह कोड के साथ अच्छी तरह मेल खाता है. अलग-अलग चरणों में नोड की संख्या बढ़ जाती है. आप मान सकते हैं कि नोड की संख्या में होने वाली हर बढ़ोतरी, grow() को किए जाने वाले कॉल है. JS हीप ग्राफ़ (नीला ग्राफ़) उतना आसान नहीं है. सबसे सही तरीकों के हिसाब से, पहली डिप असल में ज़बरदस्ती कूड़ा कलेक्शन है. कचरा इकट्ठा करें बटन को दबाकर ऐसा किया जाता है. जैसे-जैसे रिकॉर्डिंग आगे बढ़ती है, वैसे-वैसे JS हीप साइज़ बढ़ता जाता है. यह स्वाभाविक और उम्मीद के मुताबिक है: JavaScript कोड हर बटन क्लिक पर डीओएम नोड बना रहा है. जब यह 10 लाख वर्णों की स्ट्रिंग बनाता है, तब बहुत ज़्यादा काम करता है. यहां खास बात यह है कि JS हीप शुरुआत की तुलना में ज़्यादा तरीके से खत्म हुआ है (यहां "शुरुआत" का मतलब है, ज़बरदस्ती कचरा इकट्ठा करने के बाद का). असल में, अगर आपको JS हीप साइज़ या नोड साइज़ बढ़ाने का यह पैटर्न दिखता है, तो इसका मतलब मेमोरी लीक हो सकता है.

हीप स्नैपशॉट की मदद से, अलग-अलग डीओएम ट्री मेमोरी लीक के बारे में जानें

किसी डीओएम नोड को सिर्फ़ तभी इकट्ठा किया जा सकता है, जब पेज के डीओएम ट्री या JavaScript कोड से उसका कोई रेफ़रंस न हो. किसी नोड को डीओएम ट्री से हटाने पर, उसे "डिटैच किया गया" कहा जाता है, लेकिन कुछ JavaScript अभी भी इसका रेफ़रंस देते हैं. आम तौर पर, अलग-अलग डीओएम नोड मेमोरी लीक होने की वजह होते हैं. इस सेक्शन में, आपको DevTools के हीप प्रोफ़ाइलर का इस्तेमाल करने का तरीका बताया गया है. इसकी मदद से, अलग किए गए नोड की पहचान की जा सकती है.

यहां अलग किए गए DOM नोड का एक उदाहरण दिया गया है.

var detachedTree;

function create() {
  var ul = document.createElement('ul');
  for (var i = 0; i < 10; i++) {
    var li = document.createElement('li');
    ul.appendChild(li);
  }
  detachedTree = ul;
}

document.getElementById('create').addEventListener('click', create);

कोड में रेफ़र किए गए बटन पर क्लिक करने से, दस li बच्चों वाला एक ul नोड बन जाता है. इन नोड का रेफ़रंस कोड से होता है, लेकिन ये डीओएम ट्री में मौजूद नहीं होते हैं. इसलिए, उन्हें अलग कर दिया जाता है.

हीप स्नैपशॉट अलग-अलग नोड की पहचान करने का एक तरीका है. जैसा कि नाम से ही साफ़ है, हीप स्नैपशॉट से यह पता चलता है कि स्नैपशॉट लेते समय, आपके पेज के JS ऑब्जेक्ट और DOM नोड के बीच मेमोरी कैसे बांटी जाती है.

स्नैपशॉट बनाने के लिए, DevTools खोलें और मेमोरी पैनल पर जाएं. इसके बाद, हीप स्नैपशॉट रेडियो बटन चुनें. इसके बाद, स्नैपशॉट लें बटन को दबाएं.

हीप स्नैपशॉट लें

स्नैपशॉट को प्रोसेस और लोड होने में कुछ समय लग सकता है. काम पूरा हो जाने के बाद, उसे बाएं पैनल से चुनें (इसका नाम HAMP SNAPSHOTS है).

अलग किए गए DOM ट्री खोजने के लिए, क्लास फ़िल्टर टेक्स्टबॉक्स में Detached टाइप करें.

डिटैच्ड नोड के लिए फ़िल्टर करना

एक अलग पेड़ की जांच करने के लिए कैरेट को बड़ा करें.

अलग हो रहे पेड़ की जांच करना

पीले रंग से हाइलाइट किए गए नोड में, JavaScript कोड से सीधे तौर पर रेफ़रंस होते हैं. लाल रंग से हाइलाइट किए गए नोड में सीधे तौर पर रेफ़रंस नहीं होते हैं. वे सिर्फ़ इसलिए ज़िंदा हैं, क्योंकि वे पीले नोड के पेड़ का हिस्सा हैं. आम तौर पर, आपको पीले रंग के नोड पर ध्यान देना होता है. अपना कोड ठीक करें, ताकि पीला नोड ज़रूरत से ज़्यादा समय तक जीवित न रहे. साथ ही, आपको पीले नोड के ट्री से जुड़े लाल नोड से भी छुटकारा मिल जाएगा.

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

पीले रंग के नोड की जांच की जा रही है

ऐलोकेशन टाइमलाइन की मदद से, JS हीप मेमोरी लीक की पहचान करना

ऐलोकेशन टाइमलाइन एक और टूल है, जो आपके JS हीप में मेमोरी लीक को ट्रैक करने में आपकी मदद कर सकता है.

ऐलोकेशन की टाइमलाइन दिखाने के लिए, इस कोड का इस्तेमाल करें:

var x = [];

function grow() {
  x.push(new Array(1000000).join('x'));
}

document.getElementById('grow').addEventListener('click', grow);

जब भी कोड में रेफ़र किया गया बटन पुश किया जाता है, तो x कलेक्शन में 10 लाख वर्णों वाली स्ट्रिंग जुड़ जाती है.

ऐलोकेशन टाइमलाइन रिकॉर्ड करने के लिए, DevTools खोलें, प्रोफ़ाइल पैनल पर जाएं, असाइन टाइमलाइन रेडियो बटन चुनें. शुरू करें बटन दबाएं, वह कार्रवाई करें जिसके बारे में आपको लगता है कि इससे मेमोरी लीक हो रही है और इसके बाद, रिकॉर्डिंग बंद करें बटन (रिकॉर्डिंग बंद करने के लिए बटन) दबाएं.

रिकॉर्ड करते समय, ध्यान दें कि ऐलोकेशन टाइमलाइन पर कोई नीले रंग का बार दिखता है या नहीं, जैसा कि नीचे दिए गए स्क्रीनशॉट में दिखाया गया है.

नए आवंटन

वे नीले बार, नई मेमोरी के आवंटन को दिखाते हैं. ये नई मेमोरी, आपकी मेमोरी लीक होने से जुड़ी समस्याओं के लिए इस्तेमाल की जा सकती हैं. कंस्ट्रक्टर पैनल को फ़िल्टर करने के लिए, किसी बार पर ज़ूम करके, सिर्फ़ वे ऑब्जेक्ट दिखाए जा सकते हैं जिन्हें तय समयसीमा में बांटा गया था.

ऐलोकेशन को ज़ूम करने की टाइमलाइन

ऑब्जेक्ट को बड़ा करें और ऑब्जेक्ट पैनल में इसके बारे में ज़्यादा जानकारी देखने के लिए, इसकी वैल्यू पर क्लिक करें. उदाहरण के लिए, नीचे दिए गए स्क्रीनशॉट में, हाल ही में असाइन किए गए ऑब्जेक्ट की जानकारी देखकर, यह देखा जा सकता है कि इसे Window स्कोप में x वैरिएबल के लिए असाइन किया गया था.

ऑब्जेक्ट की जानकारी

फ़ंक्शन के हिसाब से, मेमोरी के बंटवारे की जांच करें

JavaScript फ़ंक्शन से मेमोरी का बंटवारा देखने के लिए, मेमोरी पैनल में असाइनमेंट से जुड़ी सैंपलिंग टाइप का इस्तेमाल करें.

रिकॉर्ड ऐलोकेशन प्रोफ़ाइलर

  1. असाइनमेंट का सैंपलिंग रेडियो बटन चुनें. अगर पेज पर कोई वर्कर है, तो स्टार्ट बटन के बगल में मौजूद ड्रॉपडाउन मेन्यू का इस्तेमाल करके, उसे प्रोफ़ाइलिंग टारगेट के तौर पर चुना जा सकता है.
  2. शुरू करें बटन दबाएं.
  3. जिस पेज की जांच करनी है उस पर कार्रवाइयां करें.
  4. अपनी सभी कार्रवाइयां पूरी करने के बाद, बंद करें बटन दबाएं.

DevTools आपको फ़ंक्शन के हिसाब से, मेमोरी के बंटवारे का ब्रेकडाउन दिखाता है. डिफ़ॉल्ट व्यू हैवी (सबसे ऊपर ऊपर) होता है, जिसमें वे फ़ंक्शन दिखते हैं जिनमें सबसे ऊपर सबसे ज़्यादा मेमोरी दी गई थी.

ऐलोकेशन प्रोफ़ाइल

बार-बार कूड़ा इकट्ठा करने वाली चीज़ों का पता लगाएं

अगर आपका पेज बार-बार रुकता है, तो हो सकता है कि आपकी साइट का कचरा इकट्ठा करने से जुड़ी समस्याएं आ रही हों.

बार-बार कचरे के कलेक्शन का पता लगाने के लिए, Chrome टास्क मैनेजर या टाइमलाइन की मेमोरी रिकॉर्डिंग का इस्तेमाल किया जा सकता है. टास्क मैनेजर में, मेमोरी या JavaScript मेमोरी के बार-बार बढ़ने और घटने वाली वैल्यू, कूड़े के संग्रह को बार-बार दिखाने का काम करती हैं. टाइमलाइन रिकॉर्डिंग में, JS हीप या नोड काउंट वाले ग्राफ़ के बार-बार बढ़ने और गिरने से पता चलता है कि बार-बार कचरा इकट्ठा होता है.

समस्या की पहचान करने के बाद, ऐलोकेशन टाइमलाइन रिकॉर्डिंग का इस्तेमाल करके यह पता लगाया जा सकता है कि मेमोरी कहां बांटी जा रही है और किन फ़ंक्शन की वजह से आवंटन हो रहा है.