Menghabiskan memori dan membengkak — apa itu, penyebab dan cara menghindari

Penulis: IT Sectr Diterbitkan: 2026-07-28 Waktu membaca: 10 mnt

Kebocoran memori — salah satu masalah paling berbahaya dalam pengembangan mobile. Memori aplikasi terus meningkat hingga mencapai batas yang ditetapkan oleh sistem operasi, setelah itu terjadi OutOfMemoryError atau penghentian paksa. Menurut Square Engineering, sekitar 40% aplikasi Android memiliki setidaknya satu kebocoran memori yang hanya dapat dideteksi saat profiling. Mari kita bahas penyebab dan metode pencegahan pertumbuhan memori.

Poin utama

  • GC reachability — objek tidak dihapus jika ada referensi aktif dari root set
  • Referensi statis ke Activity atau Context — penyebab kebocoran paling umum di Android
  • LeakCanary — alat standar untuk deteksi kebocoran otomatis di Android
  • WeakReference — solusi untuk referensi yang tidak boleh menghalangi pengumpulan sampah
  • Komponen Lifecycle-aware secara otomatis membatalkan langganan saat view dihancurkan

Apa itu kebocoran memori dan pembengkakan aplikasi?

Kebocoran memori (memory leak) — situasi di mana objek yang tidak lagi dibutuhkan aplikasi tetap berada di heap karena ada referensi aktif dari root set (GC Root). Pengumpul sampah menganggap objek tersebut hidup dan tidak menghapusnya.

Pembengkakan memori (memory bloat) — masalah yang lebih luas ketika aplikasi mengonsumsi lebih banyak memori daripada yang diperlukan untuk menjalankan tugas saat ini. Penyebab: caching berlebihan, duplikasi objek, struktur data yang tidak optimal, dan fragmentasi heap.

Di Android setiap aplikasi dialokasikan heap terbatas (biasanya 64-512 MB tergantung perangkat dan versi OS). Di iOS batasannya kurang ketat, tetapi sistem mengirimkan peringatan memori saat mendekati batas.

KarakteristikAndroidiOS
Batas heap64-512 MB (tergantung perangkat)Implisit (sistem)
Pengumpulan sampahART (Concurrent, Compact)ARC (Automatic Reference Counting)
Mekanisme kebocoranReferensi GC RootSiklus retain (siklus referensi kuat)
HasilOutOfMemoryErrorPeringatan memori → penghentian

Menurut Facebook Engineering Blog, kebocoran memori adalah penyebab ~15% laporan crash di aplikasi mobile. Di Android, ditambah ANR karena seringnya jeda GC saat kekurangan memori.

Pola kebocoran memori tipikal di Android dan iOS

Referensi statis ke Activity — klasik kebocoran Android. Jika bidang statis atau singleton menyimpan referensi ke Activity, Activity tidak akan dikumpulkan oleh GC bahkan setelah finish(), selama singleton masih hidup. Activity adalah objek berat yang berisi hierarki View, resources, dan Context.

kotlin
object LeakHolder {
    var activityRef: Activity ?= null // bocor: referensi statis ke Activity
}

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle ?= null) {
        super.onCreate(savedInstanceState)
        LeakHolder.activityRef = this // ❌ MainActivity tidak akan pernah dikumpulkan oleh GC
    }
}

Kelas anonim dan lambda — secara implisit menyimpan referensi ke kelas luar. Jika Runnable atau Callback diteruskan ke layanan eksternal dan Activity dihancurkan, objek kelas anonim masih menggantung di antrian dan tidak membiarkan Activity pergi ke pengumpulan sampah.

  • Handler dengan penundaan — jika Activity dihancurkan tetapi Handler.postDelayed belum dijalankan, Activity bocor
  • Thread dan AsyncTask — saat rotasi layar Activity dibuat ulang, tetapi Thread lama masih menyimpan referensi ke Activity lama
  • Retrofit/Callback — Callback anonim menyimpan referensi ke presenter atau fragment
  • Pengamat (Observers) — langganan LiveData atau RxJava tanpa pembatalan saat onDestroy

Di iOS masalah utamanya adalah retain cycles: dua objek saling menyimpan referensi kuat dan ARC tidak bisa menghitung nol untuk keduanya. Kasus tipikal: closure yang menangkap self secara kuat, dan self yang menyimpan referensi ke closure.

Bagaimana cara mendeteksi kebocoran memori?

LeakCanary — pustaka dari Square untuk deteksi kebocoran otomatis di Android. Setelah Activity atau Fragment dihancurkan, ia memeriksa apakah objek telah dikumpulkan oleh GC. Jika tidak — ia membuat heap dump dan menampilkan trace kebocoran.

kotlin
// LeakCanary 2.x — integrasi otomatis melalui Application
class ExampleApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        // LeakCanary menginstal otomatis di build debug
        // melalui ContentProvider — pengaturan tanpa kode
    }
}

// Panggilan pemeriksaan paksa
AppWatcher.objectWatcher.watch(watchedObject, "leak description")

Android Studio Profiler — alat bawaan untuk pemantauan memori secara real-time. Memungkinkan merekam heap dump, menemukan objek mencurigakan (Retained Size > 1 MB), dan melacak jalur GC root ke setiap objek.

Untuk iOS gunakan Xcode Memory Graph Debugger. Ini memvisualisasikan graf objek dalam memori, menampilkan retain cycles dan memungkinkan deteksi instan referensi melingkar. Juga tersedia Instruments > Allocations untuk pemantauan jangka panjang.

Strategi pencegahan kebocoran

WeakReference — mekanisme dasar untuk referensi yang tidak boleh menghalangi pengumpulan sampah. Jika GC memutuskan untuk menghapus objek, WeakReference mengembalikan null. Digunakan untuk callback, listener, dan referensi ke komponen UI dari thread latar belakang.

Komponen Lifecycle-aware — pendekatan arsitektural yang diimplementasikan di Android Jetpack (Lifecycle, LiveData, Flow, coroutines). Langganan secara otomatis dibatalkan saat onDestroy, yang menghilangkan kelas kebocoran utama.

kotlin
class MyViewModel : ViewModel() {
    private val _data = MutableLiveData<List<User>>()
    val data: LiveData<List<User>> get() = _data

    fun loadData() {
        viewModelScope.launch {
            val result = repository.fetchData()
            _data.postValue(result)
            // coroutine otomatis membatalkan saat onCleared()
        }
    }
}

viewModelScope dan lifecycleScope — CoroutineScope bawaan di Android yang dibatalkan pada peristiwa siklus hidup yang sesuai. Ini menghilangkan kebocoran melalui coroutine — skenario paling umum dalam pengembangan Android modern.

  • Jangan gunakan referensi statis ke Context, Activity, View atau Fragment
  • Batalkan semua langganan RxJava di disposeBag / CompositeDisposable saat onDestroy
  • Gunakan [weak self] / [unowned self] di closure iOS untuk mencegah retain cycles
  • Periksa Bitmap dan objek besar — harus didaur ulang atau dinolkan

Alat profiling memori

Memory Profiler in Android Studio — alat utama untuk pemantauan heap. Menampilkan alokasi live, snapshot heap, jumlah objek per jenis. Memungkinkan merekam dump dan menganalisisnya di MAT (Memory Analyzer Tool) untuk menemukan objek mencurigakan.

Eclipse MAT — penganalisis heap dump desktop. Setelah memuat file HPROF dari Android Studio, MAT membangun pohon dominator, menampilkan retain size setiap objek, dan menawarkan analisis otomatis kebocoran mencurigakan melalui Leak Suspects Report.

Xcode Memory Graph — debugger visual untuk retain cycles. Saat menekan tombol Memory Graph Debugger, Xcode menghentikan aplikasi, membangun graf lengkap objek dalam memori, dan menyorot retain cycles dengan warna merah.

AlatPlatformFitur
LeakCanaryAndroidDeteksi kebocoran otomatis setelah destroy
Memory ProfilerAndroid StudioHeap dump + alokasi live
Eclipse MATAndroidPohon dominator, Leak Suspects Report
Memory GraphiOS (Xcode)Visualisator retain cycles

Menurut Google I/O 2023, aplikasi yang menggunakan LeakCanary di build debug mengurangi jumlah crash terkait memori sebesar 30-50% dalam 2 bulan pertama setelah implementasi. Disarankan menambahkan LeakCanary pada fase onboarding proyek.

Pertanyaan yang sering diajukan

Apa perbedaan kebocoran memori dan pembengkakan?

Kebocoran — objek yang tidak dapat diakses kode tetapi tidak dihapus GC karena referensi aktif. Pembengkakan — aplikasi menyimpan objek yang secara logis diperlukan tetapi dalam jumlah berlebihan (misalnya, cache 50 MB pada aplikasi yang berjalan seberat 80 MB). Pembengkakan diatasi secara arsitektural, kebocoran — melalui manajemen referensi yang benar.

Bagaimana LeakCanary menemukan kebocoran?

LeakCanary menggunakan ObjectWatcher — setelah onDestroy() Activity, ia membuat WeakReference ke Activity dan menjalankan GC. Jika setelah 5 detik WeakReference tidak dibersihkan, LeakCanary membuat heap dump, menganalisis rantai referensi terpendek dari GC Root ke objek, dan menampilkan tumpukan kebocoran yang tepat dengan nama file dan baris kode.

Mengapa Bitmap sering menyebabkan OutOfMemoryError?

Bitmap menggunakan memori di luar heap Java di memori native (native heap). Ukuran satu Bitmap = lebar × tinggi × 4 byte (ARGB_8888). Foto 12 MP (4000×3000) memakan 48 MB. Android tidak selalu dapat membebaskan memori native tepat waktu, yang saat beberapa Bitmap menumpuk menyebabkan OOM bahkan dengan heap Java yang cukup.

Apa itu retain cycle di iOS?

Retain cycle — situasi di ARC ketika dua objek saling menyimpan referensi kuat dan penghitung referensi tidak pernah mencapai nol. Contoh tipikal: ViewController dengan referensi kuat ke closure, dan closure menangkap self secara kuat. Solusi: gunakan [weak self] atau [unowned self] di closure.

Berapa ukuran heap maksimum di Android?

Ukuran heap tergantung pada perangkat dan versi Android. Untuk perangkat lama (API 15-24) — 64-128 MB. Untuk perangkat modern (API 25+) — 256-512 MB. Nilai pasti dapat diperoleh melalui ActivityManager.getMemoryClass(). Untuk aplikasi besar (game, editor) ada largeHeap=true di manifest, yang memberikan hingga 1 GB.

Ringkasan

  • Kebocoran memori — objek tidak dihapus GC karena referensi aktif dari root set; pembengkakan — konsumsi memori berlebihan tanpa kebocoran jelas
  • Referensi statis ke Activity, Context, View — penyebab nomor satu kebocoran di Android; solusi — WeakReference atau Application Context
  • Kelas anonim dan lambda secara implisit menyimpan referensi ke kelas luar; callback yang tidak dibatalkan — penyebab kedua paling umum
  • LeakCanary — standar deteksi kebocoran otomatis di Android; integrasi memakan waktu 5 menit dan mengurangi tingkat crash sebesar 30-50%
  • lifecycleScope dan viewModelScope secara otomatis membatalkan coroutine saat destroy, menghilangkan seluruh kelas kebocoran
  • Retain cycles di iOS diselesaikan dengan weak/unowned self di closure dan delegate
  • Profil memori setidaknya sekali per sprint — heap dump dengan MAT atau Memory Graph harus menjadi bagian dari code review

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.

Diskusikan proyek

Baca juga