Heap Dump (dump heap) — snapshot memori dinamis aplikasi yang berisi informasi lengkap tentang semua objek yang hidup: kelasnya, ukurannya, referensi timbal balik, dan aksesibilitas dari simpul akar (GC roots). Heap Dump adalah alat utama untuk menganalisis kebocoran memori dan mengoptimalkan konsumsi sumber daya. Menurut Android Developers, analisis heap dump memungkinkan mendeteksi hingga 95% kebocoran memori, termasuk referensi siklik, listener yang terlupa, dan referensi statis yang tidak dibebaskan.
Poin Utama
Heap dump adalah dump lengkap heap mesin virtual — area memori tempat semua objek yang dibuat secara dinamis ditempatkan. Di Java dan Kotlin ini adalah Dalvik/ART di Android, di Swift dan Objective-C — heap yang dikelola ARC di iOS. Heap dump mencatat setiap objek, kelasnya, ukuran, bidang, referensi ke objek lain, dan flag aksesibilitas dari GC roots (variabel stack, bidang statis, referensi JNI).
Tujuan utama heap dump adalah mendeteksi kebocoran memori. Kebocoran terjadi ketika aplikasi terus mempertahankan referensi ke objek yang tidak lagi diperlukan, mencegah pengumpulannya oleh garbage collector (atau pembebasan melalui ARC). Penyebab umum: listener peristiwa yang tidak didaftarkan saat activity dihancurkan; singleton dengan referensi ke konteks; closure yang menangkap self; koleksi statis yang ditambahi data tanpa penghapusan. Heap dump memberikan gambaran yang akurat: objek mana yang „hidup", mana yang berlebihan, dan siapa yang tepat merujuk padanya.
Menurut data Google I/O, lebih dari 60% laporan crash aplikasi Android terkait dengan OutOfMemoryError, dan dalam 80% kasus penyebab utamanya adalah kebocoran memori yang dapat dideteksi melalui heap dump. Untuk aplikasi iOS situasinya serupa: kebocoran akibat retain cycles adalah salah satu penyebab umum crash yang terdeteksi melalui instrument Allocations di Xcode.
Heap dump harus dilakukan pada gejala berikut: aplikasi mengonsumsi memori secara linear pada tindakan berulang (navigasi bolak-balik antar layar); setelah layar selesai bekerja, memori tidak kembali ke tingkat awal; muncul OutOfMemoryError atau peringatan memory warning di iOS; aplikasi berhenti karena melebihi batas memori (EXC_RESOURCE_RESOURCE di iOS). Pengumpulan heap dump secara teratur adalah bagian dari protokol budaya rekayasa di proyek seluler besar seperti Instagram dan Spotify.
Android Studio menyediakan Memory Profiler — alat bawaan untuk menangkap heap dump secara real-time. Dapat diakses melalui View → Tool Windows → Profiler. Setelah meluncurkan aplikasi, pilih sesi, buka tab Memory dan klik Dump Java Heap. Android Studio menjeda aplikasi, melakukan dump heap ART dan memuat hasilnya untuk analisis. File dump memiliki format .hprof — standar HPROF yang kompatibel dengan sebagian besar penganalisis memori.
Setelah dump dimuat, Android Studio menampilkan tabel objek dengan kolom: Allocations (jumlah instance), Native Size (memori di luar heap ART), Shallow Size (memori objek itu sendiri), Retained Size (memori objek dengan seluruh subgraf). Pemfilteran berdasarkan nama kelas, pengurutan berdasarkan retained size, dan pencarian berdasarkan paket memungkinkan menemukan area bermasalah dengan cepat.
// Kebocoran tipikal — listener tidak dibatalkan di onDestroy
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) terlewat
// → Activity tidak akan dikumpulkan GC, heap dump akan menunjukkan kebocoran
}
}
Tab Dominator Tree menunjukkan objek yang menahan jumlah memori terbesar. Jika sebuah objek dihapus dari dominator tree, seluruh memori yang ditahannya tersedia untuk pengumpulan. Ini adalah alat kunci: alih-alih memeriksa ribuan objek, Anda fokus pada 10-20 objek yang mengendalikan 80-90% memori. Menurut Google, analisis dominator tree adalah cara paling efektif untuk menemukan titik kebocoran, mengurangi waktu analisis dari jam menjadi menit.
Xcode Instruments menyediakan dua alat untuk bekerja dengan heap dump: Allocations — menangkap dump heap dengan grafik konsumsi real-time; Leaks — pencarian otomatis kebocoran melalui analisis retain cycles. Allocations menampilkan semua objek di heap, ukurannya, jumlah pembuatan (allocations) dan pembebasan (deallocations). Perbedaan antara jumlah pembuatan dan pembebasan untuk kelas tertentu menunjukkan potensi kebocoran.
Menangkap heap dump di Allocations dilakukan dengan tombol Snapshot Memory — alat menjeda aplikasi dan mengambil dump lengkap. Setelah itu, tampilan standar tersedia: daftar objek berdasarkan kelas, pohon panggilan (call tree) untuk setiap objek, dan generator laporan. Tidak seperti Android Studio, Xcode tidak menggunakan .hprof, melainkan menyimpan data dalam format .trace miliknya sendiri, kompatibel dengan Instruments.
// Kebocoran iOS tipikal — retain cycle melalui closure
class NetworkManager {
var onComplete: ((Data) -> Void)?
func startRequest() {
// ❌ Closure menangkap self — retain cycle
onComplete = { data in
self.process(data)
}
}
func process(_ data: Data) {}
}
Leaks instrument secara otomatis mendeteksi retain cycles dan kebocoran melalui analisis grafik referensi. Ini menandai objek yang bocor dengan ikon ungu dan menunjukkan jalur ke akar (GC root). Untuk memperbaiki retain cycle, cukup tambahkan [weak self] atau [unowned self] ke closure. Menjalankan Leaks instrument secara teratur adalah tahap CI wajib di tim yang menggunakan Swift untuk pengembangan iOS.
// Perbaikan — referensi lemah ke self
onComplete = { [weak self] data in
guard let self else { return }
self.process(data)
}
Untuk analisis heap dump yang benar, perlu memahami tiga metrik kunci. Shallow size — volume memori yang langsung ditempati oleh objek: bidang, header, dan perataannya. Untuk objek Java/Kotlin tipikal, shallow size adalah 16-40 byte. Retained size — shallow size objek ditambah total shallow size semua objek yang hanya dapat diakses melalui objek ini (yaitu akan menjadi sampah saat dihapus). Retained size-lah yang menunjukkan dampak nyata objek pada konsumsi memori.
| Metrik | Deskripsi | Contoh |
|---|---|---|
| Shallow size | Ukuran objek itu sendiri dalam byte | Bitmap (100×100) = 40 016 B |
| Retained size | Shallow size + semua yang ditahannya | Activity dengan View Tree = 2-5 MB |
| Deep size | Retained size + objek bersarang dari graf lain | ScrollView dengan adapter = 10-50 MB |
Dominator tree — struktur di mana setiap objek merujuk ke „dominator"-nya — objek yang mengontrol aksesibilitasnya. Jika dominator dihapus, semua objek di subpohonnya menjadi sampah. Analisis dominator tree adalah cara tercepat untuk menemukan objek yang menahan memori paling banyak. Menurut Eclipse MAT (Memory Analyzer Tool), 90% kebocoran terdeteksi melalui peninjauan top-20 dominator tree dalam 5 menit.
Proses analisis kebocoran melalui heap dump terdiri dari beberapa langkah. Langkah 1: lakukan tindakan yang seharusnya membebaskan memori (tutup layar, selesaikan operasi). Langkah 2: panggil GC (System.gc() di Android, snapshot paksa di Xcode) dan buat heap dump. Langkah 3: temukan objek yang seharusnya telah dimusnahkan (misalnya instance Activity setelah finish). Langkah 4: untuk objek yang mencurigakan, jalankan Path to GC Roots — rantai referensi yang membuat objek tetap hidup. Referensi terakhir dalam rantai adalah penyebab kebocoran.
Fungsi Path to GC Roots tersedia di Android Studio Profiler, Eclipse MAT, dan Xcode Instruments. Ini menunjukkan rantai referensi terpendek dari GC root ke objek bermasalah. Dengan mengecualikan referensi lemah (weak) dan lunak (soft), Anda mendapatkan hanya referensi kuat (strong) — yang benar-benar menghalangi pengumpulan. Menurut statistik Square Engineering, 70% kebocoran di aplikasi Android disebabkan hanya oleh dua pola: referensi statis ke Activity atau Context dan listener yang terdaftar tetapi tidak dibatalkan pendaftarannya.
// Contoh kebocoran melalui referensi statis
object AppCache {
private val cache = mutableMapOf<String, Any>()
fun storeActivityReference(activity: Activity) {
cache["current_activity"] = activity // ❌ Kebocoran!
}
}
// Perbaikan: referensi lemah
object AppCacheFixed {
private val cache = mutableMapOf<String, WeakReference<Any>>()
}
Teknik comparison mode — salah satu metode paling efektif untuk menemukan kebocoran. Buat heap dump sebelum dan setelah tindakan berulang (misalnya lima kali navigasi ke layar dan kembali). Bandingkan jumlah instance kelas kunci: jika jumlah Activity meningkat, meskipun semua aktivitas telah ditutup — ini adalah kebocoran. Android Studio dan Eclipse MAT mendukung perbandingan otomatis dump dengan penyorotan perbedaan. Menurut Google, perbandingan dump memungkinkan menemukan kebocoran yang tidak terlihat dalam analisis satu kali karena akumulasi efek.
Berdasarkan analisis heap dump di proyek nyata, praktik optimalisasi memori yang terbukti telah dikembangkan. Gunakan WeakReference untuk cache, callback, dan referensi ke konteks di objek berumur panjang. Batalkan pendaftaran listener di onPause/onDestroy untuk Android dan deinit untuk iOS. Hindari koleksi statis besar — jika perlu, gunakan LruCache dengan batasan ukuran. Optimalkan Bitmap: muat gambar dengan inSampleSize yang tepat, gunakan Glide atau Picasso dengan cache disk.
Sertakan penangkapan heap dump secara teratur dalam CI. Konfigurasikan tugas yang menjalankan tes UI terinstrumentasi, melakukan skenario pengguna utama, dan membandingkan heap dump dengan baseline. Jika retained size naik lebih dari 5% dari baseline, build ditandai sebagai regresi. Pendekatan ini dipraktikkan di Airbnb, Uber, dan perusahaan lain dengan persyaratan kualitas tinggi. Menurut Uber Engineering, penerapan analisis heap dump otomatis di CI mengurangi jumlah bug terkait memori sebesar 70% dalam satu kuartal.
// Contoh tugas Gradle untuk heap dump otomatis di CI
task profileMemory(type: Exec) {
commandLine 'adb', 'shell',
'am start -n com.example/.MainActivity'
// Menunggu pemuatan
doLast {
exec { commandLine 'adb', 'shell',
'am broadcast -a com.example.DUMP_HEAP' }
}
}
Pertanyaan yang Sering Diajukan
Shallow size — ukuran objek itu sendiri (bidang + header). Retained size — ukuran objek ditambah semua objek yang akan menjadi sampah saat dihapus. Retained size adalah indikator utama dampak objek pada konsumsi memori.
Melalui Android Studio Profiler pilih perangkat dan proses, klik Dump Java Heap. Alternatif — melalui baris perintah: adb shell am dumpheap PID /sdcard/dump.hprof, lalu adb pull.
Heap dump mencakup semua objek hidup. Jika aplikasi menggunakan cache, Bitmap, atau memproses data besar, dump dapat mencapai ratusan megabita. Filter berdasarkan kelas atau gunakan Eclipse MAT untuk memuat hanya indeks.
Ya, gunakan Eclipse MAT (Memory Analyzer Tool) — alat gratis untuk menganalisis .hprof. Mendukung dominator tree, path to GC roots, perbandingan dump, dan pencarian kebocoran otomatis melalui Leak Suspects Report.
Dump itu sendiri — ya, karena pengambilan dump menjeda semua utas (stop-the-world). Tanpa dump — tidak. Lakukan dump dalam kondisi terkendali (lingkungan uji, CI), bukan di produksi.
Ringkasan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga