हीप डंप कैप्चर करें

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

इस पेज पर, Android Studio में हीप डंप इकट्ठा करने और उनका विश्लेषण करने के लिए उपलब्ध टूल के बारे में बताया गया है. इसके अलावा, dumpsys की मदद से, कमांड लाइन से अपने ऐप्लिकेशन की मेमोरी की जांच की जा सकती है. साथ ही, Logcat में गार्बेज कलेक्शन (जीसी) इवेंट देखे जा सकते हैं.

आपको अपने ऐप्लिकेशन की मेमोरी का प्रोफ़ाइल क्यों बनाना चाहिए

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

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

ऐसी प्रोग्रामिंग के बारे में जानकारी पाएं जिससे आपके ऐप्लिकेशन की मेमोरी का इस्तेमाल कम हो सकता है. इसके लिए, अपने ऐप्लिकेशन की मेमोरी मैनेज करना लेख पढ़ें.

हीप डंप के बारे में खास जानकारी

हीप डंप कैप्चर करने के लिए, मेमोरी के इस्तेमाल का विश्लेषण करें (हीप डंप) टास्क चुनें हीप डंप कैप्चर करने के लिए, प्रोफ़ाइलर: 'ऐप्लिकेशन' को डीबग करने लायक (पूरा डेटा) के तौर पर चलाएं का इस्तेमाल करें. हीप डंप करते समय, Java की मेमोरी का इस्तेमाल कुछ समय के लिए बढ़ सकता है. यह सामान्य है, क्योंकि हीप डंप उसी प्रोसेस में होता है जिसमें आपका ऐप्लिकेशन होता है. साथ ही, डेटा इकट्ठा करने के लिए कुछ मेमोरी की ज़रूरत होती है. हीप डंप कैप्चर करने के बाद, आपको यह दिखेगा:

Android Studio Profiler में Heap Dump व्यू.

क्लासों की सूची में यह जानकारी दिखती है:

  • Allocations: हीप में किए गए ऐलोकेशन की संख्या.
  • नेटिव साइज़: इस ऑब्जेक्ट टाइप के लिए इस्तेमाल की गई कुल नेटिव मेमोरी (बाइट में). आपको यहां Java में असाइन किए गए कुछ ऑब्जेक्ट के लिए मेमोरी दिखेगी, क्योंकि Android, कुछ फ़्रेमवर्क क्लास के लिए नेटिव मेमोरी का इस्तेमाल करता है. जैसे, Bitmap.

  • शैलो साइज़: इस ऑब्जेक्ट टाइप के लिए इस्तेमाल की गई कुल Java मेमोरी (बाइट में).

  • रिटेन किया गया साइज़: इस क्लास के सभी इंस्टेंस की वजह से, रिटेन की गई मेमोरी का कुल साइज़ (बाइट में).

कुछ हीप को फ़िल्टर करने के लिए, हीप मेन्यू का इस्तेमाल करें:

  • ऐप्लिकेशन हीप (डिफ़ॉल्ट): यह प्राइमरी हीप है, जिस पर आपका ऐप्लिकेशन मेमोरी असाइन करता है.
  • इमेज हीप: यह सिस्टम बूट इमेज होती है. इसमें ऐसी क्लास होती हैं जिन्हें बूट होने के दौरान पहले से लोड किया जाता है. यहां किए गए असाइनमेंट कभी नहीं हटते.
  • ज़ायगोट हीप: यह कॉपी-ऑन-राइट हीप है. इसमें Android सिस्टम में किसी ऐप्लिकेशन प्रोसेस को फ़ोर्क किया जाता है.

ड्रॉप-डाउन मेन्यू में दिए गए विकल्पों का इस्तेमाल करके, यह चुनें कि आपको आवंटन कैसे व्यवस्थित करने हैं:

  • क्लास के हिसाब से क्रम में लगाएं (डिफ़ॉल्ट): इससे सभी क्लास के नाम के हिसाब से, सभी असाइनमेंट को ग्रुप किया जाता है.
  • पैकेज के हिसाब से क्रम से लगाएं: पैकेज के नाम के आधार पर सभी असाइनमेंट को ग्रुप करता है.

क्लास के ड्रॉप-डाउन मेन्यू का इस्तेमाल करके, क्लास के ग्रुप को फ़िल्टर करें:

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

उदाहरण पैनल खोलने के लिए, क्लास के नाम पर क्लिक करें. सूची में दिए गए हर इंस्टेंस में यह जानकारी शामिल होती है:

  • डेप्थ: किसी भी जीसी रूट से चुने गए इंस्टेंस तक पहुंचने के लिए, कम से कम हॉप की संख्या.
  • नेटिव साइज़: नेटिव मेमोरी में इस इंस्टेंस का साइज़. यह कॉलम सिर्फ़ Android 7.0 और इसके बाद के वर्शन पर दिखता है.
  • शैलो साइज़: Java मेमोरी में इस इंस्टेंस का साइज़.
  • रखा गया साइज़: मेमोरी का वह साइज़ जिस पर इस इंस्टेंस का कंट्रोल होता है. यह डॉमिनटर ट्री के हिसाब से होता है.

उदाहरण की जानकारी दिखाने के लिए, किसी उदाहरण पर क्लिक करें. इसमें फ़ील्ड और रेफ़रंस शामिल हैं. Java में, सामान्य फ़ील्ड और रेफ़रंस टाइप, स्ट्रक्चर्ड टाइप , ऐरे , और प्रिमिटिव डेटा टाइप होते हैं. सोर्स कोड में उससे जुड़े इंस्टेंस या लाइन पर जाने के लिए, किसी फ़ील्ड या रेफ़रंस पर राइट क्लिक करें.

  • फ़ील्ड: इस इंस्टेंस में मौजूद सभी फ़ील्ड दिखाता है.
  • रेफ़रंस: इसमें उदाहरण टैब में हाइलाइट किए गए ऑब्जेक्ट के हर रेफ़रंस को दिखाया जाता है.
Heap Dump टूल विंडो में Instances, Fields, और References व्यू.

मेमोरी लीक ढूंढना

मेमोरी लीक से जुड़ी क्लास को तुरंत फ़िल्टर करने के लिए, क्लास ड्रॉप-डाउन खोलें और गतिविधि/फ़्रैगमेंट लीक दिखाएं चुनें. Android Studio, आपके ऐप्लिकेशन में Activity और Fragment इंस्टेंस के लिए, मेमोरी लीक करने वाली क्लास दिखाता है.

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

  • Activity या Context के ऐसे रेफ़रंस जो लंबे समय तक इस्तेमाल किए जाते हैं. इनसे होस्ट किए गए Compose कंपोज़िशन ग्राफ़ (जैसे कि ComposeView और इसके सब-कंपोज़ेबल) की जानकारी लीक हो सकती है.
  • Jetpack Compose के स्टेट ऑब्जेक्ट (MutableState), स्टेट होल्डर या Context कैप्चर करने वाले लैम्ब्डा लीक हो रहे हैं.
  • DisposableEffect के onDispose ब्लॉक में लिसनर या ऑब्ज़र्वर को हटाना भूल जाना.
  • नॉन-स्टैटिक इनर क्लास, जैसे कि a Runnable, जो Activity इंस्टेंस को होल्ड कर सकती है.
  • ऐसी कैश मेमोरी जो ऑब्जेक्ट को ज़रूरत से ज़्यादा समय तक सेव रखती हैं.

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

जांच के लिए मेमोरी लीक ट्रिगर करें

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

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

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

हीप डंप रिकॉर्डिंग को एक्सपोर्ट और इंपोर्ट करना

प्रोफ़ाइलर में, पिछली रिकॉर्डिंग टैब से हीप डंप फ़ाइल को एक्सपोर्ट और इंपोर्ट किया जा सकता है. Android Studio, रिकॉर्डिंग को .hprof फ़ाइल के तौर पर सेव करता है.

इसके अलावा, jhat जैसे किसी दूसरे .hprof फ़ाइल विश्लेषक का इस्तेमाल करने के लिए, आपको .hprof फ़ाइल को Android फ़ॉर्मैट से Java SE .hprof फ़ाइल फ़ॉर्मैट में बदलना होगा. फ़ाइल फ़ॉर्मैट बदलने के लिए, {android_sdk}/platform-tools/ डायरेक्ट्री में दिए गए hprof-conv टूल का इस्तेमाल करें. hprof-conv कमांड को दो आर्ग्युमेंट के साथ चलाएं: ओरिजनल .hprof फ़ाइल का नाम और बदली गई .hprof फ़ाइल को सेव करने की जगह. इसमें नई .hprof फ़ाइल का नाम भी शामिल होना चाहिए. उदाहरण के लिए:

hprof-conv heap-original.hprof heap-converted.hprof

अन्य संसाधन