Heap Dump (हीप डंप) एप्लिकेशन की डायनामिक मेमोरी का एक स्नैपशॉट है जिसमें सभी जीवित ऑब्जेक्ट्स के बारे में पूरी जानकारी होती है: उनके क्लास, आकार, आपसी संदर्भ और GC रूट्स से पहुँच क्षमता। Heap Dump मेमोरी लीक के विश्लेषण और संसाधन खपत को अनुकूलित करने का प्राथमिक उपकरण है। Android Developers के अनुसार, heap dump विश्लेषण 95% तक मेमोरी लीक का पता लगा सकता है, जिसमें चक्रीय संदर्भ, भूले हुए listeners और मुक्त न किए गए स्थिर संदर्भ शामिल हैं।
मुख्य बातें
Heap dump वर्चुअल मशीन के हीप का पूर्ण डंप है — मेमोरी क्षेत्र जहाँ सभी डायनामिक रूप से बनाए गए ऑब्जेक्ट रहते हैं। Java और Kotlin में यह Android पर Dalvik/ART हीप है, Swift और Objective-C में यह iOS पर ARC-प्रबंधित हीप है। Heap dump प्रत्येक ऑब्जेक्ट, उसके क्लास, आकार, फ़ील्ड, अन्य ऑब्जेक्ट्स के संदर्भ और GC रूट्स से पहुँच क्षमता फ़्लैग को कैप्चर करता है।
Heap dump का मुख्य उद्देश्य मेमोरी लीक का पता लगाना है। लीक तब होता है जब कोई एप्लिकेशन उन ऑब्जेक्ट्स के संदर्भों को बनाए रखता है जिनकी अब आवश्यकता नहीं है, जिससे गार्बेज कलेक्टर द्वारा उनका संग्रहण अवरुद्ध हो जाता है। सामान्य कारण: activity के नष्ट होने पर अनरजिस्टर न किए गए इवेंट listeners; कॉन्टेक्स्ट के संदर्भ वाले सिंगलटन; self को कैप्चर करने वाले क्लोज़र; स्थिर संग्रह जिनमें डेटा बिना हटाए जोड़ा जाता है। Heap dump सटीक चित्र प्रदान करता है: कौन से ऑब्जेक्ट “जीवित” हैं, कौन से अनावश्यक हैं, और वास्तव में उन्हें कौन संदर्भित कर रहा है।
Google I/O के अनुसार, 60% से अधिक Android एप्लिकेशन क्रैश रिपोर्ट OutOfMemoryError से संबंधित हैं, और 80% मामलों में मूल कारण मेमोरी लीक है जो heap dump के माध्यम से पता लगाया जा सकता है। iOS एप्लिकेशन के लिए स्थिति समान है: retain cycles के कारण लीक क्रैश के सबसे सामान्य कारणों में से एक है, जिसे Xcode में Allocations इंस्ट्रूमेंट के माध्यम से पहचाना जाता है।
Heap dump निम्नलिखित लक्षणों पर किया जाना चाहिए: एप्लिकेशन दोहराए जाने वाले कार्यों (स्क्रीन के बीच आगे-पीछे नेविगेशन) के दौरान रैखिक रूप से मेमोरी की खपत करता है; स्क्रीन बंद करने के बाद मेमोरी आधार स्तर पर वापस नहीं आती है; OutOfMemoryError या iOS पर मेमोरी चेतावनी दिखाई देती है; एप्लिकेशन मेमोरी सीमा पार करने के कारण समाप्त हो जाता है। Instagram और Spotify जैसी बड़ी मोबाइल परियोजनाओं में नियमित heap dump संग्रह इंजीनियरिंग संस्कृति प्रोटोकॉल का हिस्सा है।
Android Studio Memory Profiler प्रदान करता है — रियल टाइम में heap dump कैप्चर करने के लिए एक अंतर्निहित उपकरण। View → Tool Windows → Profiler के माध्यम से पहुँचा जा सकता है। एप्लिकेशन लॉन्च करने के बाद, सत्र चुनें, Memory टैब पर जाएँ और Dump Java Heap पर क्लिक करें। Android Studio एप्लिकेशन को रोकता है, ART हीप डंप करता है और विश्लेषण के लिए परिणाम लोड करता है। डंप फ़ाइल .hprof प्रारूप में होती है — HPROF मानक जो अधिकांश मेमोरी विश्लेषकों के साथ संगत है।
डंप लोड करने के बाद, Android Studio कॉलम के साथ एक ऑब्जेक्ट तालिका प्रदर्शित करता है: Allocations (इंस्टेंस संख्या), Native Size (ART हीप के बाहर मेमोरी), Shallow Size (ऑब्जेक्ट की स्वयं की मेमोरी), Retained Size (संपूर्ण उपग्राफ सहित ऑब्जेक्ट की मेमोरी)। क्लास नाम से फ़िल्टरिंग, retained size द्वारा सॉर्टिंग और पैकेज द्वारा खोज आपको समस्या क्षेत्रों को जल्दी से खोजने की अनुमति देती है।
// सामान्य लीक — onDestroy में अनरजिस्टर न किया गया listener
class MainActivity : AppCompatActivity() {
private val sensorManager by lazy {
getSystemService(SENSOR_SERVICE) as SensorManager
}
private val listener = MySensorListener()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
sensorManager.registerListener(listener,
sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT),
SensorManager.SENSOR_DELAY_NORMAL)
}
override fun onDestroy() {
super.onDestroy()
// ❌ sensorManager.unregisterListener(listener) गायब
// → Activity GC नहीं होगी, heap dump लीक दिखाएगा
}
}
Dominator Tree टैब उन ऑब्जेक्ट्स को दिखाता है जो सबसे अधिक मेमोरी रखते हैं। यदि किसी ऑब्जेक्ट को dominator tree से हटा दिया जाता है, तो उसके द्वारा रखी गई सारी मेमोरी गार्बेज कलेक्शन के लिए उपलब्ध हो जाती है। यह एक महत्वपूर्ण उपकरण है: हज़ारों ऑब्जेक्ट्स को स्कैन करने के बजाय, आप 10–20 पर ध्यान केंद्रित करते हैं जो 80–90% मेमोरी को नियंत्रित करते हैं। Google के अनुसार, dominator tree विश्लेषण लीक बिंदु खोजने का सबसे प्रभावी तरीका है, जो विश्लेषण समय को घंटों से मिनटों तक कम करता है।
Xcode Instruments heap dump के साथ काम करने के लिए दो उपकरण प्रदान करता है: Allocations — रियल टाइम खपत ग्राफ़ के साथ हीप डंप कैप्चर करना; Leaks — retain cycle विश्लेषण के माध्यम से स्वचालित लीक खोज। Allocations हीप में सभी ऑब्जेक्ट्स, उनके आकार, निर्माणों की संख्या और मुक्तियों को प्रदर्शित करता है। किसी विशिष्ट क्लास के लिए निर्माणों और मुक्तियों की संख्या के बीच का अंतर संभावित लीक दर्शाता है।
Allocations में heap dump कैप्चर Snapshot Memory बटन से किया जाता है — उपकरण एप्लिकेशन को रोकता है और पूर्ण डंप लेता है। उसके बाद, मानक दृश्य उपलब्ध हैं: क्लास के अनुसार ऑब्जेक्ट सूची, प्रत्येक ऑब्जेक्ट के लिए कॉल ट्री और रिपोर्ट जनरेटर। Android Studio के विपरीत, Xcode .hprof का उपयोग नहीं करता है, बल्कि डेटा को Instruments के साथ संगत अपने स्वयं के .trace प्रारूप में संग्रहीत करता है।
// सामान्य iOS लीक — क्लोज़र के माध्यम से retain cycle
class NetworkManager {
var onComplete: ((Data) -> Void)?
func startRequest() {
// ❌ क्लोज़र self को कैप्चर करता है — retain cycle
onComplete = { data in
self.process(data)
}
}
func process(_ data: Data) {}
}
Leaks इंस्ट्रूमेंट संदर्भ ग्राफ़ विश्लेषण के माध्यम से retain cycles और लीक का स्वचालित रूप से पता लगाता है। यह लीक करने वाले ऑब्जेक्ट्स को बैंगनी आइकन से चिह्नित करता है और रूट (GC root) का पथ दिखाता है। retain cycle को खत्म करने के लिए, क्लोज़र कैप्चर में [weak self] या [unowned self] जोड़ना पर्याप्त है। Swift का उपयोग करने वाली टीमों में Leaks इंस्ट्रूमेंट का नियमित चलना CI पाइपलाइन का एक अनिवार्य चरण है।
// समाधान — self का कमज़ोर संदर्भ
onComplete = { [weak self] data in
guard let self else { return }
self.process(data)
}
Heap dump के सही विश्लेषण के लिए तीन प्रमुख मीट्रिक को समझना आवश्यक है। Shallow size ऑब्जेक्ट द्वारा सीधे घेरी गई मेमोरी की मात्रा है: इसके फ़ील्ड, हेडर और संरेखण। एक सामान्य Java/Kotlin ऑब्जेक्ट के लिए, shallow size 16–40 बाइट होता है। Retained size ऑब्जेक्ट का shallow size और उन सभी ऑब्जेक्ट्स का कुल shallow size है जो केवल इस ऑब्जेक्ट के माध्यम से पहुँच योग्य हैं। Retained size मेमोरी खपत पर ऑब्जेक्ट के वास्तविक प्रभाव को दर्शाता है।
| मीट्रिक | विवरण | उदाहरण |
|---|---|---|
| Shallow size | ऑब्जेक्ट का स्वयं का आकार बाइट्स में | Bitmap (100×100) = 40 016 B |
| Retained size | Shallow size + वह सब जो वह रखता है | View Tree के साथ Activity = 2–5 MB |
| Deep size | Retained size + अन्य ग्राफ़ से नेस्टेड ऑब्जेक्ट | एडेप्टर के साथ ScrollView = 10–50 MB |
Dominator tree एक संरचना है जहाँ प्रत्येक ऑब्जेक्ट अपने “डॉमिनेटर” को संदर्भित करता है — वह ऑब्जेक्ट जो उसकी पहुँच क्षमता को नियंत्रित करता है। यदि डॉमिनेटर हटा दिया जाता है, तो उसके उपवृक्ष के सभी ऑब्जेक्ट गार्बेज बन जाते हैं। डॉमिनेटर ट्री विश्लेषण यह पता लगाने का सबसे तेज़ तरीका है कि कौन सा ऑब्जेक्ट सबसे अधिक मेमोरी रखता है। Eclipse MAT के अनुसार, 90% लीक 5 मिनट में top-20 dominator tree की समीक्षा करके पता लगाए जाते हैं।
Heap dump के माध्यम से लीक विश्लेषण की प्रक्रिया में कई चरण शामिल हैं। चरण 1: वह कार्य करें जो मेमोरी को मुक्त करना चाहिए (स्क्रीन बंद करें, ऑपरेशन समाप्त करें)। चरण 2: GC को कॉल करें और heap dump लें। चरण 3: उन ऑब्जेक्ट्स को खोजें जो नष्ट हो जाने चाहिए थे। चरण 4: संदिग्ध ऑब्जेक्ट के लिए Path to GC Roots चलाएँ — संदर्भों की श्रृंखला जो ऑब्जेक्ट को जीवित रखती है। श्रृंखला में अंतिम संदर्भ लीक का कारण है।
Path to GC Roots फ़ंक्शन Android Studio Profiler, Eclipse MAT और Xcode Instruments में उपलब्ध है। यह GC रूट से समस्या ऑब्जेक्ट तक संदर्भों की सबसे छोटी श्रृंखला दिखाता है। कमज़ोर और नरम संदर्भों को छोड़कर, आपको केवल मजबूत संदर्भ मिलते हैं — जो वास्तव में गार्बेज कलेक्शन को रोकते हैं। Square Engineering के अनुसार, Android एप्लिकेशन में 70% लीक केवल दो पैटर्न के कारण होते हैं: Activity या Context के स्थिर संदर्भ और पंजीकृत लेकिन अनरजिस्टर न किए गए listeners।
// स्थिर संदर्भ के माध्यम से लीक का उदाहरण
object AppCache {
private val cache = mutableMapOf<String, Any>()
fun storeActivityReference(activity: Activity) {
cache["current_activity"] = activity // ❌ लीक!
}
}
// समाधान: कमज़ोर संदर्भ
object AppCacheFixed {
private val cache = mutableMapOf<String, WeakReference<Any>>()
}
तुलना मोड तकनीक लीक का पता लगाने के सबसे प्रभावी तरीकों में से एक है। बार-बार की जाने वाली कार्रवाई से पहले और बाद में heap dump लें। प्रमुख क्लासेस की इंस्टेंस संख्या की तुलना करें: यदि सभी गतिविधियाँ बंद होने के बावजूद Activity की संख्या बढ़ गई है — यह लीक है। Android Studio और Eclipse MAT अंतरों को उजागर करने के साथ स्वचालित डंप तुलना का समर्थन करते हैं। Google के अनुसार, डंप तुलना प्रभाव के संचय के कारण एकल विश्लेषण में अदृश्य लीक का पता लगाती है।
वास्तविक परियोजनाओं में heap dump विश्लेषण के आधार पर, सिद्ध मेमोरी ऑप्टिमाइज़ेशन प्रथाएँ विकसित की गई हैं। WeakReference का उपयोग करें कैश, कॉलबैक और लंबे समय तक जीवित रहने वाले ऑब्जेक्ट्स में कॉन्टेक्स्ट संदर्भों के लिए। Listeners को अनरजिस्टर करें Android के लिए onPause/onDestroy और iOS के लिए deinit में। बड़े स्थिर संग्रहों से बचें — यदि आवश्यक हो, तो आकार सीमा के साथ LruCache का उपयोग करें। Bitmap को ऑप्टिमाइज़ करें: सही inSampleSize के साथ छवियाँ लोड करें, डिस्क कैश के साथ Glide या Picasso का उपयोग करें।
अपने CI पाइपलाइन में नियमित heap dump कैप्चर शामिल करें। एक कार्य सेट करें जो इंस्ट्रूमेंटेड UI परीक्षण चलाता है, प्रमुख उपयोगकर्ता परिदृश्यों को निष्पादित करता है और heap dump की बेसलाइन से तुलना करता है। यदि retained size बेसलाइन से 5% से अधिक बढ़ जाता है, तो बिल्ड को प्रतिगमन के रूप में चिह्नित किया जाता है। यह दृष्टिकोण Airbnb, Uber और उच्च गुणवत्ता मानकों वाली अन्य कंपनियों में अपनाया जाता है। Uber Engineering के अनुसार, CI में स्वचालित heap dump विश्लेषण लागू करने से एक तिमाही में मेमोरी संबंधित बग में 70% की कमी आई।
// CI में स्वचालित heap dump के लिए Gradle टास्क का उदाहरण
task profileMemory(type: Exec) {
commandLine 'adb', 'shell',
'am start -n com.example/.MainActivity'
// लोड होने की प्रतीक्षा
doLast {
exec { commandLine 'adb', 'shell',
'am broadcast -a com.example.DUMP_HEAP' }
}
}
अक्सर पूछे जाने वाले प्रश्न
Shallow size ऑब्जेक्ट का स्वयं का आकार है (फ़ील्ड + हेडर)। Retained size ऑब्जेक्ट का आकार और उन सभी ऑब्जेक्ट्स का आकार है जो उसके हटाने पर कचरा बन जाएँगे। Retained size मेमोरी खपत पर ऑब्जेक्ट के प्रभाव का मुख्य संकेतक है।
Android Studio Profiler के माध्यम से, डिवाइस और प्रक्रिया चुनें, Dump Java Heap पर क्लिक करें। वैकल्पिक रूप से — कमांड लाइन के माध्यम से: adb shell am dumpheap PID /sdcard/dump.hprof, फिर adb pull।
Heap dump में सभी जीवित ऑब्जेक्ट शामिल होते हैं। यदि एप्लिकेशन कैश, Bitmap या बड़े डेटा का उपयोग करता है, तो डंप सैकड़ों मेगाबाइट तक पहुँच सकता है। क्लास के अनुसार फ़िल्टर करें या केवल इंडेक्स लोड करने के लिए Eclipse MAT का उपयोग करें।
हाँ, Eclipse MAT (Memory Analyzer Tool) का उपयोग करें — .hprof फ़ाइलों के विश्लेषण के लिए एक मुफ़्त उपकरण। यह dominator tree, path to GC roots, डंप तुलना और Leak Suspects Report के माध्यम से स्वचालित लीक का पता लगाने का समर्थन करता है।
डंप स्वयं — हाँ, क्योंकि डंप संग्रह सभी थ्रेड को रोकता है। डंप के बिना — नहीं। नियंत्रित वातावरण (टेस्ट बेंच, CI) में डंप लें, प्रोडक्शन में नहीं।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें