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

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

खास जानकारी

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

खास जानकारी

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

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

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

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

मेमोरी लीक की परिभाषा आसानी से दी जा सकती है. अगर कोई साइट लगातार ज़्यादा से ज़्यादा मेमोरी का इस्तेमाल कर रही है, तो इसका मतलब है कि वह साइट लीक हो गई है. हालांकि, मेमोरी ब्लोट की समस्या का पता लगाना थोड़ा मुश्किल होता है. "बहुत ज़्यादा मेमोरी इस्तेमाल करना" किसे माना जाता है?

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

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

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

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

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

    टास्क मैनेजर खोलना

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

    JS मेमोरी की सुविधा चालू करना

इन दो कॉलम से आपको यह पता चलता है कि आपका पेज मेमोरी का इस्तेमाल कैसे कर रहा है:

  • मेमोरी कॉलम, नेटिव मेमोरी दिखाता है. डीओएम नोड, नेटिव मेमोरी में सेव किए जाते हैं. अगर यह वैल्यू बढ़ रही है, तो इसका मतलब है कि DOM नोड बन रहे हैं.
  • 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);

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

सामान्य बढ़ोतरी का उदाहरण

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

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

हीप स्नैपशॉट की मदद से, डिटैच किए गए डीओएम ट्री की मेमोरी के लीक होने का पता लगाएं

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

अलग किए गए डीओएम नोड का एक आसान उदाहरण यहां दिया गया है.

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);

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

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

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

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

स्नैपशॉट को प्रोसेस और लोड होने में कुछ समय लग सकता है. स्नैपशॉट जनरेट होने के बाद, बाईं ओर मौजूद हीप स्नैपशॉट पैनल से उसे चुनें.

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

अलग किए गए नोड के लिए फ़िल्टर करना

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

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

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

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

पीले रंग के किसी नोड की जांच करना

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

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

ऐलोकेशन टाइमलाइन को दिखाने के लिए, यह कोड देखें:

var x = [];

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

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

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

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

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

नए ऐलोकेशन

नीले रंग के ये बार, मेमोरी के नए ऐलोकेशन दिखाते हैं. मेमोरी के लिए नए ऐलोकेशन, मेमोरी लीक के संभावित उम्मीदवार होते हैं. कंस्ट्रक्टर पैनल को फ़िल्टर करने के लिए, किसी बार पर ज़ूम किया जा सकता है. इससे, सिर्फ़ वे ऑब्जेक्ट दिखेंगे जिन्हें तय समयसीमा के दौरान असाइन किया गया था.

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

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

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

फ़ंक्शन के हिसाब से मेमोरी ऐलोकेशन की जांच करना

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

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

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

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

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

बार-बार कचरा इकट्ठा करने की जगहें

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

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

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