हेप डंप कैप्चर करके देखें कि आपके ऐप्लिकेशन में कौनसे ऑब्जेक्ट, कैप्चर के समय मेमोरी का इस्तेमाल कर रहे हैं. साथ ही, मेमोरी लीक या मेमोरी के बंटवारे के उस व्यवहार की पहचान करें जिसकी वजह से ऐप्लिकेशन में रुकावट आती है, वह फ़्रीज़ हो जाता है, और यहां तक कि ऐप्लिकेशन क्रैश हो जाता है. उपयोगकर्ता के लंबे सेशन के बाद, हेप डंप लेने से खास तौर पर मदद मिलती है. ऐसा तब होता है, जब यह मेमोरी में अब भी ऐसे ऑब्जेक्ट दिखा सकता है जो वहां नहीं होने चाहिए.
इस पेज पर, Android Studio में मौजूद उन टूल के बारे में बताया गया है जिनका इस्तेमाल करके, हेप डंप इकट्ठा किए जा सकते हैं और उनका विश्लेषण किया जा सकता है. इसके अलावा, dumpsys
की मदद से कमांड लाइन से अपने ऐप्लिकेशन की मेमोरी की जांच की जा सकती है. साथ ही, Logcat में गैर-ज़रूरी डेटा हटाने (GC) से जुड़े इवेंट देखे जा सकते हैं.
आपको अपने ऐप्लिकेशन की मेमोरी की प्रोफ़ाइल क्यों बनानी चाहिए
Android, मैनेज की गई मेमोरी का एक माहौल उपलब्ध कराता है. जब Android यह पता लगाता है कि आपका ऐप्लिकेशन कुछ ऑब्जेक्ट का इस्तेमाल नहीं कर रहा है, तो गै़रबेज कलेक्टर, इस्तेमाल नहीं की गई मेमोरी को ढेर में वापस छोड़ देता है. Android, इस्तेमाल नहीं की जा रही मेमोरी को ढूंढने के तरीके को लगातार बेहतर बना रहा है. हालांकि, Android के सभी वर्शन पर किसी समय, सिस्टम को आपके कोड को कुछ समय के लिए रोकना पड़ता है. ज़्यादातर समय, वीडियो में रुकावट का पता नहीं चलता. हालांकि, अगर आपका ऐप्लिकेशन, सिस्टम से ज़्यादा तेज़ी से मेमोरी ऐलोकेट करता है, तो हो सकता है कि आपके ऐप्लिकेशन को कुछ समय तक इंतज़ार करना पड़े. ऐसा तब होता है, जब कलेक्टर आपके ऐलोकेशन को पूरा करने के लिए ज़रूरत के मुताबिक मेमोरी खाली करता है. देरी की वजह से, आपके ऐप्लिकेशन में फ़्रेम स्किप हो सकते हैं और ऐप्लिकेशन के काम करने में ज़्यादा समय लग सकता है.
अगर आपका ऐप्लिकेशन धीमा नहीं चलता है, लेकिन उसमें मेमोरी लीक होती है, तो वह बैकग्राउंड में भी उस मेमोरी को बनाए रख सकता है. इस व्यवहार की वजह से, सिस्टम की बाकी मेमोरी की परफ़ॉर्मेंस धीमी हो सकती है. ऐसा, ग़ैर-ज़रूरी ग़ैरबदली जाने वाली चीज़ों को इकट्ठा करने के इवेंट को ज़बरदस्ती चलाने की वजह से होता है. आखिर में, सिस्टम को मेमोरी वापस पाने के लिए, आपके ऐप्लिकेशन की प्रोसेस को बंद करना पड़ता है. इसके बाद, जब उपयोगकर्ता आपके ऐप्लिकेशन पर वापस आता है, तो ऐप्लिकेशन की प्रोसेस को पूरी तरह से फिर से शुरू करना होगा.
प्रोग्रामिंग के उन तरीकों के बारे में जानने के लिए जिनसे आपके ऐप्लिकेशन के लिए मेमोरी का इस्तेमाल कम किया जा सकता है, अपने ऐप्लिकेशन की मेमोरी मैनेज करना लेख पढ़ें.
हीप डंप के बारे में खास जानकारी
हीप डंप कैप्चर करने के लिए, मेमोरी के इस्तेमाल का विश्लेषण करें (हीप डंप) टास्क चुनें. इसके लिए, प्रोफ़ाइलर: 'ऐप्लिकेशन' को डीबग करने लायक (पूरा डेटा) के तौर पर चलाएं का इस्तेमाल करें. हीप को डंप करते समय, कुछ समय के लिए Java मेमोरी की मात्रा बढ़ सकती है. यह सामान्य है, क्योंकि हीप डंप उसी प्रोसेस में होता है जिसमें आपका ऐप्लिकेशन चलता है. साथ ही, डेटा इकट्ठा करने के लिए, कुछ मेमोरी की ज़रूरत होती है. हेप डंप कैप्चर करने के बाद, आपको ये चीज़ें दिखेंगी:
क्लास की सूची में यह जानकारी दिखती है:
- ऐलोकेशन: ढेर में ऐलोकेशन की संख्या.
नेटिव साइज़: इस ऑब्जेक्ट टाइप के लिए इस्तेमाल की गई नेटिव मेमोरी की कुल संख्या (बाइट में). आपको यहां Java में ऐलोकेट किए गए कुछ ऑब्जेक्ट के लिए मेमोरी दिखेगी, क्योंकि Android कुछ फ़्रेमवर्क क्लास के लिए नेटिव मेमोरी का इस्तेमाल करता है. जैसे,
Bitmap
.शैलो साइज़: इस ऑब्जेक्ट टाइप के लिए इस्तेमाल की गई कुल Java मेमोरी (बाइट में).
रिटेंन किया गया साइज़: इस क्लास के सभी इंस्टेंस की वजह से, रिटेंन की जा रही मेमोरी का कुल साइज़ (बाइट में).
कुछ खास हेप को फ़िल्टर करने के लिए, हेप मेन्यू का इस्तेमाल करें:
- ऐप्लिकेशन हेप (डिफ़ॉल्ट): यह मुख्य हेप होती है, जिस पर आपका ऐप्लिकेशन मेमोरी असाइन करता है.
- इमेज हेप: सिस्टम बूट इमेज, जिसमें बूट के समय पहले से लोड की गई क्लास होती हैं. यहां मौजूद ऐलोकेशन कभी नहीं बदलते या हटते नहीं.
- Zygote ढेर: लिखते समय कॉपी होने वाला ढेर, जहां Android सिस्टम में किसी ऐप्लिकेशन प्रोसेस को फ़ॉर्क किया जाता है.
ऐलोकेशन को व्यवस्थित करने का तरीका चुनने के लिए, 'व्यवस्था' ड्रॉप-डाउन का इस्तेमाल करें:
- क्लास के हिसाब से व्यवस्थित करें (डिफ़ॉल्ट): कक्षा के नाम के आधार पर सभी ऐलोकेशन को ग्रुप में बांटता है.
- पैकेज के हिसाब से व्यवस्थित करें: पैकेज के नाम के आधार पर सभी ऐलोकेशन को ग्रुप में बांटता है.
कक्षाओं के ग्रुप को फ़िल्टर करने के लिए, कक्षा ड्रॉप-डाउन का इस्तेमाल करें:
- सभी क्लास (डिफ़ॉल्ट): इसमें सभी क्लास दिखती हैं. इनमें लाइब्रेरी और डिपेंडेंसी से जुड़ी क्लास भी शामिल हैं.
- ऐक्टिविटी/फ़्रैगमेंट से मेमोरी लीक होने की जानकारी दिखाएं: इससे उन क्लास की जानकारी मिलती है जिनकी वजह से मेमोरी लीक हो रही है.
- प्रोजेक्ट क्लास दिखाएं: इससे सिर्फ़ वे क्लास दिखती हैं जिन्हें आपके प्रोजेक्ट में तय किया गया है.
इंस्टेंस पैनल खोलने के लिए, किसी क्लास के नाम पर क्लिक करें. सूची में दिए गए हर इंस्टेंस में ये शामिल होते हैं:
- डीपथ: किसी भी जीसी रूट से चुने गए इंस्टेंस तक की सबसे कम संख्या.
- नेटिव साइज़: नेटिव मेमोरी में इस इंस्टेंस का साइज़. यह कॉलम सिर्फ़ Android 7.0 और उसके बाद के वर्शन पर दिखता है.
- शैलो साइज़: Java मेमोरी में इस इंस्टेंस का साइज़.
- रिटेंन किया गया साइज़: डोमिनेट करने वाले ट्री के मुताबिक, इस इंस्टेंस के पास मौजूद मेमोरी का साइज़.
इंस्टेंस की जानकारी देखने के लिए, किसी इंस्टेंस पर क्लिक करें. इसमें उसके फ़ील्ड और रेफ़रंस शामिल हैं. Java में, सामान्य फ़ील्ड और रेफ़रंस टाइप में स्ट्रक्चर्ड टाइप, पंक्तियां, और प्राइमटिव डेटा टाइप शामिल हैं. सोर्स कोड में मौजूद किसी फ़ील्ड या रेफ़रंस से जुड़े इंस्टेंस या लाइन पर जाने के लिए, उस फ़ील्ड या रेफ़रंस पर दायां क्लिक करें.
- फ़ील्ड: इस इंस्टेंस में सभी फ़ील्ड दिखाता है.
- रेफ़रंस: इंस्टेंस टैब में हाइलाइट किए गए ऑब्जेक्ट का हर रेफ़रंस दिखाता है.
मेमोरी लीक ढूंढना
मेमोरी लीक से जुड़ी क्लास को तुरंत फ़िल्टर करने के लिए, क्लास ड्रॉप-डाउन खोलें और गतिविधि/फ़्रैगमेंट लीक दिखाएं चुनें. Android Studio, ऐसी क्लास दिखाता है जिनके बारे में उसे लगता है कि वे आपके ऐप्लिकेशन में Activity
और Fragment
इंस्टेंस के लिए, मेमोरी लीक का संकेत देती हैं. फ़िल्टर में दिखने वाले डेटा के टाइप में ये शामिल हैं:
Activity
के ऐसे इंस्टेंस जिन्हें मिटा दिया गया है, लेकिन अब भी उनका रेफ़रंस दिया जा रहा है.Fragment
ऐसे इंस्टेंस जिनमें मान्यFragmentManager
नहीं है, लेकिन फिर भी उनका रेफ़रंस दिया जा रहा है.
ध्यान रखें कि इन स्थितियों में फ़िल्टर, गलत नतीजे दिखा सकता है:
Fragment
बनाया गया है, लेकिन इसका इस्तेमाल अब तक नहीं किया गया है.Fragment
को कैश मेमोरी में सेव किया जा रहा है, लेकिनFragmentTransaction
के हिस्से के तौर पर नहीं.
मैन्युअल तरीके से मेमोरी लीक का पता लगाने के लिए, क्लास और इंस्टेंस की सूचियों को ब्राउज़ करें. इससे, आपको बड़े साइज़ में सेव किए गए ऑब्जेक्ट मिलेंगे. इनमें से किसी वजह से होने वाली मेमोरी लीक का पता लगाएं:
Activity
,Context
,View
,Drawable
, और अन्य ऑब्जेक्ट के लंबे समय तक मौजूद रहने वाले रेफ़रंस, जिनमेंActivity
याContext
कंटेनर का रेफ़रंस हो सकता है.- ऐसे नॉन-स्टैटिक इनर क्लास जिनमें
Activity
का इंस्टेंस हो सकता है, जैसे किRunnable
. - ऐसे कैश मेमोरी जो ज़रूरत से ज़्यादा समय तक ऑब्जेक्ट सेव रखते हैं.
जब आपको संभावित मेमोरी लीक मिलती है, तो अपनी दिलचस्पी के इंस्टेंस या सोर्स कोड लाइन पर जाने के लिए, इंस्टेंस की जानकारी में फ़ील्ड और रेफ़रंस टैब का इस्तेमाल करें.
जांच के लिए मेमोरी लीक को ट्रिगर करना
मेमोरी के इस्तेमाल का विश्लेषण करने के लिए, आपको अपने ऐप्लिकेशन कोड पर ज़्यादा से ज़्यादा दबाव डालना चाहिए और मेमोरी के रिसाव को बढ़ावा देना चाहिए. अपने ऐप्लिकेशन में मेमोरी लीक का पता लगाने का एक तरीका यह है कि हेप की जांच करने से पहले, उसे कुछ समय तक चलाएं. लीक, हेप में मौजूद ऐलोकेशन के सबसे ऊपर तक पहुंच सकती हैं. हालांकि, लीक जितनी छोटी होगी, उसे देखने के लिए आपको ऐप्लिकेशन को उतना ही ज़्यादा समय तक चलाना होगा.
इनमें से किसी एक तरीके से भी मेमोरी लीक को ट्रिगर किया जा सकता है:
- गतिविधि की अलग-अलग स्थितियों में, डिवाइस को पोर्ट्रेट से लैंडस्केप में और फिर से पोर्ट्रेट में कई बार घुमाएं. डिवाइस को घुमाने पर, अक्सर ऐप्लिकेशन से
Activity
,Context
याView
ऑब्जेक्ट लीक हो सकता है. ऐसा इसलिए होता है, क्योंकि सिस्टमActivity
को फिर से बनाता है. अगर आपके ऐप्लिकेशन में उनमें से किसी ऑब्जेक्ट का रेफ़रंस कहीं और मौजूद है, तो सिस्टम उसे ग़ैर-ज़रूरी डेटा के तौर पर हटा नहीं सकता. - अलग-अलग ऐक्टिविटी स्टेटस के दौरान, अपने ऐप्लिकेशन और किसी दूसरे ऐप्लिकेशन के बीच स्विच करना. उदाहरण के लिए, होम स्क्रीन पर जाएं और फिर अपने ऐप्लिकेशन पर वापस जाएं.
हीप डंप रिकॉर्डिंग को एक्सपोर्ट और इंपोर्ट करना
प्रोफ़ाइलर में पिछली रिकॉर्डिंग टैब से, हेप डंप फ़ाइल को एक्सपोर्ट और इंपोर्ट किया जा सकता है. 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