हीप डंप कैप्चर करके देखें कि आपके ऐप्लिकेशन में कौनसी चीज़ें, कैप्चर करने के समय मेमोरी का इस्तेमाल कर रही हैं. साथ ही, मेमोरी लीक या मेमोरी के बंटवारे के ऐसे तरीके की पहचान करें जिसकी वजह से ऐप्लिकेशन रुकता है, फ़्रीज़ होता है, और क्रैश भी हो जाता है. यह खास तौर पर तब मददगार होता है, जब उपयोगकर्ता के लंबे सेशन के बाद हीप डंप लिए जाते हैं. ऐसा इसलिए, क्योंकि इससे मेमोरी में मौजूद उन ऑब्जेक्ट के बारे में पता चल सकता है जो अब वहां नहीं होने चाहिए.
इस पेज पर, Android Studio में उपलब्ध टूल के बारे में बताया गया है. इनकी मदद से, हीप डंप इकट्ठा और उनका विश्लेषण किया जा सकता है. इसके अलावा, dumpsys की मदद से कमांड लाइन से अपने ऐप्लिकेशन की मेमोरी की जांच की जा सकती है. साथ ही, Logcat में गार्बेज कलेक्शन (जीसी) इवेंट देखे जा सकते हैं.
आपको अपने ऐप्लिकेशन की मेमोरी का प्रोफ़ाइल क्यों बनाना चाहिए
Android, मैनेज की गई मेमोरी का एनवायरमेंट उपलब्ध कराता है. जब Android को पता चलता है कि आपका ऐप्लिकेशन कुछ ऑब्जेक्ट का इस्तेमाल नहीं कर रहा है, तो गार्बेज कलेक्टर, इस्तेमाल न की गई मेमोरी को वापस हीप में भेज देता है. Android, इस्तेमाल न की गई मेमोरी का पता कैसे लगाता है, इस प्रोसेस को लगातार बेहतर बनाया जा रहा है. हालांकि, सभी Android वर्शन पर किसी समय, सिस्टम को आपके कोड को कुछ समय के लिए रोकना होगा. ज़्यादातर मामलों में, वीडियो रुकने का पता नहीं चलता. हालांकि, अगर आपका ऐप्लिकेशन, सिस्टम के डेटा इकट्ठा करने की प्रोसेस से ज़्यादा तेज़ी से मेमोरी असाइन करता है, तो हो सकता है कि आपका ऐप्लिकेशन कुछ समय के लिए रुक जाए. ऐसा तब होता है, जब कलेक्टर आपके असाइन किए गए डेटा के लिए ज़रूरी मेमोरी खाली करता है. इस वजह से, आपके ऐप्लिकेशन में फ़्रेम स्किप हो सकते हैं और परफ़ॉर्मेंस धीमी हो सकती है.
अगर आपका ऐप्लिकेशन धीमे नहीं चलता है, लेकिन मेमोरी लीक करता है, तो वह बैकग्राउंड में चलने के दौरान भी मेमोरी को बनाए रख सकता है. इस वजह से, सिस्टम की मेमोरी की परफ़ॉर्मेंस धीमी हो सकती है. ऐसा इसलिए होता है, क्योंकि इससे बेवजह गार्बेज कलेक्शन इवेंट ट्रिगर होते हैं. आखिरकार, सिस्टम को आपकी ऐप्लिकेशन प्रोसेस को बंद करना पड़ता है, ताकि मेमोरी को वापस लिया जा सके. इसके बाद, जब उपयोगकर्ता आपके ऐप्लिकेशन पर वापस आता है, तो ऐप्लिकेशन की प्रोसेस पूरी तरह से रीस्टार्ट होनी चाहिए.
प्रोग्रामिंग के ऐसे तरीकों के बारे में जानने के लिए [Manage your app's memory]memory पढ़ें जिनसे आपके ऐप्लिकेशन की मेमोरी का इस्तेमाल कम किया जा सकता है.
हीप डंप के बारे में खास जानकारी
हीप डंप कैप्चर करने के लिए, मेमोरी के इस्तेमाल का विश्लेषण करें (हीप डंप) टास्क चुनें. इसके लिए, प्रोफ़ाइलर: डीबग किए जा सकने वाले ऐप्लिकेशन के तौर पर 'app' चलाएं (पूरा डेटा) का इस्तेमाल करें. हीप डंप करते समय, Java मेमोरी की मात्रा कुछ समय के लिए बढ़ सकती है. यह सामान्य है, क्योंकि हीप डंप आपके ऐप्लिकेशन की प्रोसेस में ही होता है. साथ ही, डेटा इकट्ठा करने के लिए कुछ मेमोरी की ज़रूरत होती है. हीप डंप कैप्चर करने के बाद, आपको यह दिखेगा:
क्लास की सूची में यह जानकारी दिखती है:
- Allocations: हीप में किए गए ऐलोकेशन की संख्या.
नेटिव साइज़: इस ऑब्जेक्ट टाइप के लिए इस्तेमाल की गई कुल नेटिव मेमोरी (बाइट में). आपको यहां Java में असाइन किए गए कुछ ऑब्जेक्ट के लिए मेमोरी दिखेगी, क्योंकि Android, कुछ फ़्रेमवर्क क्लास के लिए नेटिव मेमोरी का इस्तेमाल करता है. जैसे,
Bitmap.शैल साइज़: इस ऑब्जेक्ट टाइप के लिए इस्तेमाल की गई कुल Java मेमोरी (बाइट में).
रिटेन किया गया साइज़: इस क्लास के सभी इंस्टेंस की वजह से, रिटेन की गई मेमोरी का कुल साइज़ (बाइट में).
कुछ हीप को फ़िल्टर करने के लिए, हीप मेन्यू का इस्तेमाल करें:
- ऐप्लिकेशन हीप (डिफ़ॉल्ट): यह वह प्राइमरी हीप है जिस पर आपका ऐप्लिकेशन मेमोरी असाइन करता है.
- इमेज हीप: यह सिस्टम बूट इमेज होती है. इसमें ऐसी क्लास होती हैं जिन्हें बूट होने के दौरान पहले से लोड किया जाता है. यहां किए गए असाइनमेंट कभी नहीं हटते.
- ज़ायगोट हीप: यह कॉपी-ऑन-राइट हीप है. इसमें Android सिस्टम में किसी ऐप्लिकेशन प्रोसेस को फ़ोर्क किया जाता है.
ड्रॉप-डाउन मेन्यू में दिए गए विकल्पों का इस्तेमाल करके, यह चुनें कि आपको ऐसेट का बंटवारा कैसे करना है:
- क्लास के हिसाब से क्रम में लगाएं (डिफ़ॉल्ट): क्लास के नाम के आधार पर, सभी असाइनमेंट को ग्रुप करता है.
- पैकेज के हिसाब से क्रम से लगाएं: इससे सभी पैकेज को उनके नाम के हिसाब से ग्रुप किया जाता है.
क्लास के ड्रॉप-डाउन मेन्यू का इस्तेमाल करके, क्लास के ग्रुप को फ़िल्टर करें:
- सभी क्लास (डिफ़ॉल्ट): इसमें सभी क्लास दिखती हैं. इनमें लाइब्रेरी और डिपेंडेंसी की क्लास भी शामिल हैं.
- गतिविधि/फ़्रैगमेंट लीक दिखाएं: इससे मेमोरी लीक करने वाली क्लास दिखती हैं.
- प्रोजेक्ट क्लास दिखाएं: इससे सिर्फ़ आपके प्रोजेक्ट में तय की गई क्लास दिखती हैं.
उदाहरण पैनल खोलने के लिए, क्लास के नाम पर क्लिक करें. सूची में दिए गए हर इंस्टेंस में यह जानकारी शामिल होती है:
- डेप्थ: किसी भी जीसी रूट से चुने गए इंस्टेंस तक पहुंचने के लिए, कम से कम हॉप की संख्या.
- नेटिव साइज़: नेटिव मेमोरी में इस इंस्टेंस का साइज़. यह कॉलम सिर्फ़ Android 7.0 और इसके बाद के वर्शन पर दिखता है.
- शैलो साइज़: Java मेमोरी में इस इंस्टेंस का साइज़.
- रिटेन किया गया साइज़: मेमोरी का वह साइज़ जिस पर इस इंस्टेंस का कंट्रोल होता है. यह डॉमिनटर ट्री के हिसाब से होता है.
इंस्टेंस की जानकारी दिखाने के लिए, किसी इंस्टेंस पर क्लिक करें. इसमें इसके फ़ील्ड और रेफ़रंस शामिल हैं. Java में सामान्य फ़ील्ड और रेफ़रंस टाइप, स्ट्रक्चर्ड टाइप
, ऐरे
, और प्रिमिटिव डेटा टाइप
होते हैं. सोर्स कोड में उससे जुड़े इंस्टेंस या लाइन पर जाने के लिए, किसी फ़ील्ड या रेफ़रंस पर राइट क्लिक करें.
- फ़ील्ड: इस इंस्टेंस में मौजूद सभी फ़ील्ड दिखाता है.
- रेफ़रंस: इसमें उदाहरण टैब में हाइलाइट किए गए ऑब्जेक्ट के हर रेफ़रंस को दिखाया जाता है.
डुप्लीकेट बिटमैप का पता लगाना
Android Studio Narwhal 4 और उसके बाद के वर्शन में, Heap Dump व्यू में भी डुप्लीकेट बिटमैप का पता लगाया जा सकता है.
उन्हें ढूंढने का तरीका यहां बताया गया है:
- Android Studio में, Profiler टैब खोलें
- हीप डंप (या मेमोरी के इस्तेमाल का विश्लेषण करें) पर क्लिक करें. इसके बाद, रिकॉर्ड पर क्लिक करके अपने ऐप्लिकेशन की मौजूदा मेमोरी की स्थिति का स्नैपशॉट लें.
- विश्लेषण के नतीजों में, पीले रंग के चेतावनी वाले त्रिकोण ⚠️ को स्कैन करें. Android Studio इसका इस्तेमाल, एक से ज़्यादा बार सेव किए जा रहे डुप्लीकेट बिटमैप को फ़्लैग करने के लिए करता है.
- इसके अलावा, प्रोफ़ाइलर हेडर पर जाएं और इसके हिसाब से फ़िल्टर करें: चुनें. इसके बाद, डुप्लीकेट बिटमैप सेटिंग चुनें.
- फ़्लैग की गई किसी भी एंट्री पर क्लिक करके, बिटमैप की झलक वाला पैनल खोलें. इससे आपको यह पता चलेगा कि बार-बार उल्लंघन करने वाली इमेज कौनसी है.
- इस विज़ुअल पुष्टि का इस्तेमाल करके, अपने कोड में मौजूद फ़ालतू लोडिंग लॉजिक का पता लगाएं. साथ ही, बेहतर कैश मेमोरी रणनीति लागू करें.
मेमोरी लीक ढूंढना
मेमोरी लीक से जुड़ी क्लास को तुरंत फ़िल्टर करने के लिए, क्लास ड्रॉप-डाउन खोलें और गतिविधि/फ़्रैगमेंट लीक दिखाएं चुनें. 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 फ़ाइल के तौर पर सेव करता है.
इसके अलावा, अगर आपको .hprof फ़ाइल के लिए jhat जैसे किसी दूसरे फ़ाइल विश्लेषक का इस्तेमाल करना है, तो आपको .hprof फ़ाइल को Android फ़ॉर्मैट से Java SE .hprof फ़ाइल फ़ॉर्मैट में बदलना होगा. फ़ाइल फ़ॉर्मैट बदलने के लिए, {android_sdk}/platform-tools/ डायरेक्ट्री में दिए गए hprof-conv टूल का इस्तेमाल करें. दो आर्ग्युमेंट के साथ hprof-conv कमांड चलाएं: ओरिजनल .hprof फ़ाइल का नाम और बदली गई .hprof फ़ाइल को सेव करने की जगह. इसमें नई .hprof फ़ाइल का नाम भी शामिल होना चाहिए. उदाहरण के लिए:
hprof-conv heap-original.hprof heap-converted.hprof