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 cycle-এর কারণে লিক ক্র্যাশের সবচেয়ে সাধারণ কারণগুলোর মধ্যে একটি, যা Xcode-এ Allocations ইন্সট্রুমেন্টের মাধ্যমে চিহ্নিত করা হয়।
Heap dump নিম্নলিখিত লক্ষণগুলিতে করা উচিত: অ্যাপ্লিকেশন পুনরাবৃত্তিমূলক কাজের সময় রৈখিকভাবে মেমোরি খরচ করে; স্ক্রিন বন্ধ করার পর মেমোরি বেসলাইনে ফিরে আসে না; OutOfMemoryError বা iOS-এ মেমোরি সতর্কতা দেখা দেয়; মেমোরি সীমা অতিক্রম করার কারণে অ্যাপ্লিকেশন টার্মিনেট হয়। Instagram এবং Spotify-এর মতো বড় মোবাইল প্রকল্পে নিয়মিত heap dump সংগ্রহ ইঞ্জিনিয়ারিং সংস্কৃতি প্রোটোকলের অংশ।
Android Studio Memory Profiler প্রদান করে — রিয়েল টাইমে heap dump ক্যাপচারের জন্য একটি বিল্ট-ইন টool। 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 থেকে সরানো হয়, তাহলে তার ধরে রাখা সমস্ত মেমোরি গার্বেজ কালেকশনের জন্য উপলব্ধ হয়। এটি একটি মূল টool: হাজার হাজার অবজেক্ট স্ক্যান করার পরিবর্তে, আপনি 10–20টিতে ফোকাস করেন যা 80–90% মেমোরি নিয়ন্ত্রণ করে। Google-এর মতে, dominator tree বিশ্লেষণ লিক পয়েন্ট খুঁজে বের করার সবচেয়ে কার্যকর উপায়, যা বিশ্লেষণের সময় ঘন্টা থেকে মিনিটে কমিয়ে আনে।
Xcode Instruments heap dump-এর সাথে কাজ করার জন্য দুটি টool প্রদান করে: Allocations — রিয়েল টাইম খরচ গ্রাফ সহ হিপ ডাম্প ক্যাপচার; Leaks — retain cycle বিশ্লেষণের মাধ্যমে স্বয়ংক্রিয় লিক সনাক্তকরণ। Allocations হিপে থাকা সমস্ত অবজেক্ট, তাদের আকার, নির্মাণের সংখ্যা এবং মুক্তির সংখ্যা প্রদর্শন করে। একটি নির্দিষ্ট ক্লাসের জন্য নির্মাণ এবং মুক্তির সংখ্যার মধ্যে পার্থক্য সম্ভাব্য লিক নির্দেশ করে।
Allocations-এ heap dump ক্যাপচার Snapshot Memory বাটনের মাধ্যমে করা হয় — টoolটি অ্যাপ্লিকেশন থামায় এবং সম্পূর্ণ ডাম্প নেয়। তারপর, স্ট্যান্ডার্ড ভিউ উপলব্ধ: ক্লাস অনুসারে অবজেক্ট তালিকা, প্রতিটি অবজেক্টের জন্য কল ট্রি এবং রিপোর্ট জেনারেটর। 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 বন্ধ হওয়া সত্ত্বেও 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 ফাইল বিশ্লেষণের জন্য একটি বিনামূল্যের টool। এটি dominator tree, path to GC roots, ডাম্প তুলনা এবং Leak Suspects Report-এর মাধ্যমে স্বয়ংক্রিয় লিক সনাক্তকরণ সমর্থন করে।
ডাম্প নিজেই — হ্যাঁ, কারণ ডাম্প সংগ্রহ সমস্ত থ্রেড থামায় (stop-the-world)। ডাম্প ছাড়া — না। নিয়ন্ত্রিত পরিবেশে (টেস্ট বেঞ্চ, CI) ডাম্প নিন, প্রোডাকশনে নয়।
সারাংশ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন