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

पेज की परफ़ॉर्मेंस पर असर डालने वाली मेमोरी से जुड़ी समस्याओं का पता लगाने के लिए, 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);

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

वृद्धि का आसान उदाहरण

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

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

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

किसी DOM नोड को सिर्फ़ तब ग़ैर-ज़रूरी डेटा के तौर पर हटाया जा सकता है, जब पेज के DOM ट्री या 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 ढेर या नोड की संख्या वाले ग्राफ़ से पता चलता है कि बार-बार ग़ैर-ज़रूरी डेटा हटाया जा रहा है.

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