मेमोरी से जुड़ी शब्दावली

Meggin Kearney
Meggin Kearney

इस सेक्शन में, मेमोरी के विश्लेषण में इस्तेमाल किए जाने वाले सामान्य शब्दों के बारे में बताया गया है. साथ ही, यह अलग-अलग भाषाओं के लिए, मेमोरी की प्रोफ़ाइल बनाने के कई टूल पर लागू होता है.

यहां दिए गए शब्द और राय Chrome DevTools हीप प्रोफ़ाइलर से जुड़े हैं. अगर आपने कभी भी Java, .NET या किसी दूसरे मेमोरी प्रोफ़ाइलर के साथ काम किया है, तो यह आपके लिए रीफ़्रेशर हो सकता है.

ऑब्जेक्ट के साइज़

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

मेमोरी का विज़ुअल प्रज़ेंटेशन

कोई ऑब्जेक्ट दो तरीकों से मेमोरी को होल्ड कर सकता है:

  • सीधे ऑब्जेक्ट से.
  • सीधे तौर पर दूसरे ऑब्जेक्ट के रेफ़रंस होल्ड करके, और इस तरह से उन ऑब्जेक्ट को कूड़ा इकट्ठा करने वाले व्यक्ति से अपने-आप नष्ट होने से रोकना. इसे कम शब्दों में जीसी के तौर पर जाना जाता है.

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

हल्का और बरकरार रखा गया साइज़

उथला आकार

यह उस मेमोरी का साइज़ होता है जो ऑब्जेक्ट के पास होती है.

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

रेंडरर मेमोरी, उस प्रोसेस की पूरी मेमोरी होती है जहां जांच किए गए पेज को रेंडर किया जाता है: नेटिव मेमोरी + JS पेज की हीप मेमोरी + पेज से शुरू किए गए सभी काम करने वाले लोगों की JS हीप मेमोरी. इसके बावजूद, कचरा इकट्ठा करने की अपने-आप होने वाली प्रोसेस की मदद से, एक छोटा ऑब्जेक्ट भी बहुत ज़्यादा मेमोरी को सेव होने से रोक सकता है.

रखा गया साइज़

यह उस मेमोरी का साइज़ है जो ऑब्जेक्ट के मिटने के बाद, अपने-आप खाली हो जाती है. इसमें उन डिपेंडेंट ऑब्जेक्ट भी शामिल होते हैं जिन्हें GC रूट से ऐक्सेस नहीं किया जा सकता.

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

कई अंदरूनी GC रूट मौजूद हैं जिनमें से ज़्यादातर, उपयोगकर्ताओं के लिए दिलचस्प नहीं हैं. ऐप्लिकेशन के हिसाब से, रूट इस तरह के होते हैं:

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

मेमोरी ग्राफ़ एक रूट से शुरू होता है, जो ब्राउज़र का window ऑब्जेक्ट या Node.js मॉड्यूल का Global ऑब्जेक्ट हो सकता है. आपके पास यह कंट्रोल नहीं होता कि इस रूट ऑब्जेक्ट को जीसी कैसे किया जाए.

रूट ऑब्जेक्ट को कंट्रोल नहीं किया जा सकता

जो भी रूट से ऐक्सेस नहीं किया जा सकता उसे जीसी मिल जाता है.

पेड़ों को बनाए रखने वाली चीज़ें

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

  • नोड (या ऑब्जेक्ट) को बनाने के लिए इस्तेमाल किए गए कंस्ट्रक्टर फ़ंक्शन के नाम का इस्तेमाल करके, उन्हें लेबल किया जाता है.
  • एज को प्रॉपर्टी के नाम का इस्तेमाल करके लेबल किया जाता है.

हीप प्रोफ़ाइलर का इस्तेमाल करके प्रोफ़ाइल रिकॉर्ड करने का तरीका जानें. हीप प्रोफ़ाइलर की रिकॉर्डिंग में हम कुछ ऐसी चीज़ देख सकते हैं जो देखने लायक हैं, जैसे कि दूरी: GC रूट से दूरी. अगर एक ही तरह के करीब-करीब सभी ऑब्जेक्ट एक ही दूरी पर हैं और कुछ ऑब्जेक्ट ज़्यादा दूरी पर हैं, तो इनके बारे में जानना चाहिए.

रूट से दूरी

डॉमिनेटर

डॉमिनेटर ऑब्जेक्ट में एक ट्री स्ट्रक्चर होता है, क्योंकि हर ऑब्जेक्ट का सिर्फ़ एक डॉमिनेटर होता है. हो सकता है कि किसी ऑब्जेक्ट के डॉमिनेटर में उस ऑब्जेक्ट के सीधे रेफ़रंस न हों जिस पर वह हावी हो. इसका मतलब है कि डॉमिनेटर का ट्री, ग्राफ़ का स्पैनिंग ट्री नहीं है.

इस डायग्राम में:

  • नोड 1 नोड 2 पर हावी है
  • नोड 2, नोड 3, 4, और 6 पर निर्भर करता है
  • नोड 3 नोड 5 पर हावी है
  • नोड 5 नोड 8 पर हावी है
  • नोड 6 पर नोड 7 का असर पड़ता है

डॉमिनेटर ट्री स्ट्रक्चर

नीचे दिए गए उदाहरण में, नोड #3, #10 का डॉमिनेटर है, लेकिन #7, जीसी से #10 तक के हर आसान पाथ में भी मौजूद है. इसलिए, अगर रूट से ऑब्जेक्ट A तक के हर आसान पाथ में B मौजूद है, तो ऑब्जेक्ट B, ऑब्जेक्ट A का डॉमिनेटर होता है.

ऐनिमेशन वाला डॉमिनेटर इलस्ट्रेशन

V8 की खास बातें

मेमोरी की प्रोफ़ाइल बनाते समय, यह समझना मददगार होता है कि हीप स्नैपशॉट किसी खास तरीके से क्यों दिखते हैं. इस सेक्शन में, मेमोरी से जुड़े कुछ ऐसे विषयों के बारे में बताया गया है जो खास तौर पर V8 JavaScript वर्चुअल मशीन (V8 वीएम या वीएम) से जुड़े हैं.

JavaScript ऑब्जेक्ट का प्रतिनिधित्व

प्रिमिटिव तीन तरह के होते हैं:

  • नंबर (उदाहरण के लिए, 3.14,159..)
  • बूलियन (सही या गलत)
  • स्ट्रिंग (उदाहरण के लिए, 'वर्नर हाइज़ेनबर्ग')

ये किसी अन्य वैल्यू का रेफ़रंस नहीं दे सकते. साथ ही, ये हमेशा लीफ़ होते हैं या नोड खत्म हो जाते हैं.

नंबर को इनमें से किसी एक तरीके से सेव किया जा सकता है:

  • तुरंत दिखने वाली 31-बिट वाली पूर्णांक वैल्यू को छोटे पूर्णांक (एसएमआई) कहा जाता है या
  • हीप ऑब्जेक्ट, जिन्हें हीप नंबर कहा जाता है. हीप संख्याओं का इस्तेमाल उन वैल्यू को स्टोर करने के लिए किया जाता है जो SMI फ़ॉर्म में फ़िट नहीं होती, जैसे कि डबल्स. इसके अलावा, जब वैल्यू को बॉक्स में रखना भी ज़रूरी होता है, जैसे कि प्रॉपर्टी पर प्रॉपर्टी सेट करना.

स्ट्रिंग को इनमें से किसी एक में सेव किया जा सकता है:

  • वीएम हीप या
  • रेंडरर की मेमोरी में बाहरी लोगों को भेजा जा सकता है. एक रैपर ऑब्जेक्ट बनाया जाता है और इसका इस्तेमाल एक्सटर्नल स्टोरेज को ऐक्सेस करने के लिए किया जाता है. उदाहरण के लिए, वीएम हीप पर कॉपी करने के बजाय, वेब से मिलने वाले स्क्रिप्ट सोर्स और अन्य कॉन्टेंट को सेव किया जाता है.

नए JavaScript ऑब्जेक्ट के लिए मेमोरी, खास JavaScript हीप (या VM heap) से तय की जाती है. इन ऑब्जेक्ट को V8 का कूड़ा कलेक्टर मैनेज करता है. इसलिए, ये ऑब्जेक्ट तब तक उपलब्ध रहेंगे, जब तक उनके बारे में कम से कम एक अच्छी जानकारी मौजूद होगी.

नेटिव ऑब्जेक्ट वे सब कुछ हैं जो JavaScript हीप में नहीं हैं. हीप ऑब्जेक्ट के उलट, नेटिव ऑब्जेक्ट को V8 गार्बेज कलेक्टर पूरी तरह से मैनेज नहीं करता. साथ ही, इसे सिर्फ़ JavaScript से ऐक्सेस किया जा सकता है. इसके लिए JavaScript रैपर ऑब्जेक्ट का इस्तेमाल किया जाता है.

कॉन्स स्ट्रिंग एक ऐसा ऑब्जेक्ट है जिसमें स्ट्रिंग के जोड़े होते हैं. ये जोड़े, स्टोर की गई और फिर जोड़ी जाती हैं. यह स्ट्रिंग जोड़ने की वजह से भी होती है. कंस स्ट्रिंग कॉन्टेंट को ज़रूरत के मुताबिक ही जोड़ा जाता है. इसका उदाहरण तब होगा, जब जोड़ी गई स्ट्रिंग की सबस्ट्रिंग बनाने की ज़रूरत हो.

उदाहरण के लिए, a और b को जोड़ने पर, आपको एक स्ट्रिंग (a, b) मिलती है जो स्ट्रिंग जोड़ने का नतीजा दिखाती है. अगर बाद में d को उस नतीजे के साथ जोड़ा जाता है, तो आपको एक और कॉन्स स्ट्रिंग ((a, b), d) मिलती है.

अरे - अरे एक ऐसा ऑब्जेक्ट है जिसमें नंबर वाले बटन होते हैं. बड़ी संख्या में डेटा सेव करने के लिए, V8 वीएम में इनका इस्तेमाल बहुत ज़्यादा किया जाता है. डिक्शनरी की तरह इस्तेमाल किए जाने वाले की-वैल्यू पेयर के सेट का बैक अप, कलेक्शन के ज़रिए होता है.

एक सामान्य JavaScript ऑब्जेक्ट, स्टोर करने के लिए इस्तेमाल किए जाने वाले दो अरे टाइप में से एक हो सकता है:

  • नाम वाली प्रॉपर्टी और
  • न्यूमेरिक एलिमेंट

बहुत कम प्रॉपर्टी वाले मामलों में, उन्हें JavaScript ऑब्जेक्ट में अंदरूनी तौर पर सेव किया जा सकता है.

मैप करें-कोई ऑब्जेक्ट जो ऑब्जेक्ट के टाइप और उसके लेआउट के बारे में बताता है. उदाहरण के लिए, मैप का इस्तेमाल तेज़ प्रॉपर्टी ऐक्सेस के लिए इंप्लिसिट ऑब्जेक्ट क्रम के बारे में बताने के लिए किया जाता है.

ऑब्जेक्ट के ग्रुप

हर नेटिव ऑब्जेक्ट ग्रुप, ऐसे ऑब्जेक्ट से बना होता है जिनमें एक-दूसरे से मिलती-जुलती चीज़ें हैं. उदाहरण के लिए, एक डीओएम सबट्री जिसमें हर नोड में उसके पैरंट तक लिंक होता है और अगले चाइल्ड और अगले सिबलिंग से लिंक होता है, इस तरह एक कनेक्ट किया गया ग्राफ़ बनता है. ध्यान दें कि JavaScript हीप में नेटिव ऑब्जेक्ट नहीं दिखाए जाते हैं—इसलिए उनका साइज़ शून्य होता है. इसके बजाय, रैपर ऑब्जेक्ट बनाए जाते हैं.

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