Manajemen memori otomatis melalui pengumpulan sampah adalah mekanisme kunci platform Android, yang didasarkan pada mesin virtual ART. Menurut Google Android Documentation, 2026, pengumpul sampah membebaskan pengembang dari manajemen memori manual, secara otomatis menghapus objek yang tidak memiliki referensi lagi. Tanpa GC, setiap alokasi objek akan memerlukan pemanggilan free atau delete secara eksplisit, yang dalam ekosistem Java dengan jutaan objek per detik secara fisik tidak mungkin.
Poin Utama
Garbage Collection (GC) — adalah proses otomatis untuk mendeteksi dan membebaskan memori yang ditempati oleh objek yang tidak lagi digunakan oleh program. Dalam konteks pengembangan mobile, GC diterapkan pada platform Android melalui mesin virtual ART, serta di Java Virtual Machine standar.
Tidak seperti bahasa dengan manajemen memori manual (C, C++), di mana programmer harus secara eksplisit memanggil free atau delete, GC sepenuhnya mengambil alih tugas melacak siklus hidup objek. Pengembang membuat objek baru melalui operator new, dan pengumpul menentukan saat ketika objek menjadi tidak dapat dijangkau — yaitu, tidak ada satu pun referensi aktif yang tersisa ke objek tersebut.
Metrik utama efisiensi GC — waktu jeda (pause time) dan throughput. Jeda adalah periode di mana eksekusi aplikasi dihentikan untuk melakukan pengumpulan. Di lingkungan mobile, jeda yang lebih lama dari 8–16 milidetik terlihat sebagai frame yang terlewat (jank).
Menurut data Google I/O 2019, ART di Android 10 mengurangi jeda GC tipikal menjadi 2–4 ms, yang 70% lebih sedikit dibandingkan Dalvik di Android 4.4. Namun demikian, pengelolaan memori yang tidak tepat — alokasi objek yang sering dalam loop, pembuatan instance sementara yang tidak perlu — tetap menjadi penyebab utama masalah kinerja.
Semua implementasi GC di Java dan Android didasarkan pada beberapa algoritma fundamental, yang dikombinasikan untuk mencapai keseimbangan antara waktu jeda dan kelengkapan pembersihan. Memahami algoritma ini diperlukan untuk menulis kode yang ramah GC.
Mark-and-Sweep — algoritma paling sederhana yang bekerja dalam dua tahap. Pada tahap Mark, pengumpul menelusuri graf objek, dimulai dari referensi akar (root set) — variabel lokal, field statis, stack thread. Setiap objek yang dapat dijangkau ditandai dengan flag live. Pada tahap Sweep, pengumpul berjalan melalui seluruh heap dan membebaskan memori objek yang tidak ditandai.
Kekurangannya adalah fragmentasi memori: setelah Sweep, area bebas bergantian dengan area terisi, yang menyulitkan alokasi objek besar. Dalam skenario mobile, ini sangat penting karena heap biasanya kecil (64–512 MB di Android).
Copying Collection membagi heap menjadi dua semi-ruang (semi-spaces). Objek aktif disalin dari satu semi-ruang ke semi-ruang lainnya secara kompak, tanpa celah. Setelah penyalinan, semi-ruang lama dinyatakan sepenuhnya bebas. Algoritma ini sepenuhnya menghilangkan fragmentasi, tetapi membutuhkan memori dua kali lebih banyak.
Di lingkungan mobile, Copying Collection digunakan oleh pengumpul generasional untuk pembersihan cepat objek muda, yang secara statistik mati lebih awal (hipotesis generasi lemah).
Generational Collection membagi heap menjadi generasi: Young Generation (objek muda) dan Old Generation (objek tua yang bertahan dari beberapa pengumpulan). Pengumpulan generasi muda (Minor GC) dilakukan sering dan cepat, karena sebagian besar objek mati muda. Pengumpulan generasi tua (Major GC atau Full GC) terjadi lebih jarang, tetapi berlangsung lebih lama.
// Demonstrasi GC generasional: objek muda mati cepat
void processItems(List<Item> items) {
List<Result> results = new ArrayList<>(); // hidup sepanjang metode
for (Item item : items) {
Result r = new Result(item.getValue()); // mati seketika
if (r.isValid()) {
process(r); // r menjadi sampah
}
}
saveResults(results); // results pindah ke Old Gen
}
Dalam contoh ini, objek Result dibuat di dalam loop dan segera menjadi sampah — mereka adalah kandidat ideal untuk Young GC. Objek results hidup lebih lama dan bermigrasi ke Old Generation. Pemisahan generasi memungkinkan Minor GC membersihkan objek muda dalam hitungan milidetik, tanpa menyentuh heap lama.
Android telah melalui perjalanan dari Dalvik VM ke ART (Android Runtime), dan implementasi GC adalah salah satu perbedaan utama di antara keduanya. Memahami arsitektur GC di Android membantu menulis kode yang meminimalkan jeda pada perangkat nyata.
| Karakteristik | Dalvik (hingga 4.4) | ART (5.0+) |
|---|---|---|
| Tipe GC | Mark-and-Sweep dengan Concurrent Mark | Generasional + Concurrent |
| Jeda tipikal | 10–30 ms | 2–4 ms |
| Kompatifikasi | Tidak (hanya fragmentasi bertambah) | Ya (di latar belakang, tanpa menghentikan aplikasi) |
| Kompilasi AOT | JIT (Just-In-Time) | AOT + JIT (hibrida) |
Dalvik menggunakan kombinasi Mark-and-Sweep dengan fase concurrent. Concurrent Mark memungkinkan aplikasi untuk terus bekerja selama penelusuran graf objek, tetapi fase Sweep memerlukan penghentian semua thread (Stop-The-World). Pada perangkat dengan RAM kecil (512 MB — 1 GB), jeda mencapai 30 ms, yang menyebabkan lag antarmuka yang terlihat. Selain itu, Dalvik tidak melakukan kompaktifikasi heap, sehingga setelah penggunaan lama fragmentasi bertambah, dan alokasi objek besar (misalnya Bitmap) dapat menghasilkan OutOfMemoryError meskipun total memori bebas cukup.
ART (Android Runtime) memperkenalkan pengumpul generasional dengan kompaktifikasi concurrent. Heap dibagi menjadi tiga region: Young, Mature (analog Old Generation) dan Large Object Space (untuk objek lebih besar dari 12 KB). Pengumpulan region Young dilakukan secara paralel tanpa menghentikan thread di sebagian besar kasus. Di Android 10+ muncul Concurrent Copying — kompaktifikasi dilakukan di thread latar belakang tanpa Stop-The-World.
Berkat arsitektur ART, jeda GC tipikal berkurang menjadi 2–4 ms, dan dalam skenario dengan dominasi objek muda — menjadi 0.5–1 ms. Ini memungkinkan perangkat Android untuk memberikan 60 FPS yang stabil bahkan saat bekerja aktif dengan memori.
Di ekosistem Java terdapat beberapa implementasi GC, masing-masing dengan profil kinerja sendiri. Untuk pengembangan Android, pilihan terbatas pada ART, tetapi pengetahuan tentang Java GC berguna saat menulis bagian server aplikasi mobile dan saat pengembangan dengan Kotlin Multiplatform.
Serial GC — pengumpul single-thread dengan penghentian total aplikasi (Stop-The-World). Setiap operasi Mark, Sweep dan Compact dilakukan oleh satu thread. Kinerja rendah — tidak digunakan untuk server mobile. Hanya cocok untuk aplikasi kecil dengan heap hingga 100 MB.
Parallel GC (juga dikenal sebagai Throughput Collector) menggunakan beberapa thread untuk semua fase pengumpulan. Berorientasi pada throughput maksimum — meminimalkan waktu yang dihabiskan untuk GC relatif terhadap waktu kerja aplikasi. Diaktifkan melalui flag -XX:+UseParallelGC di JVM.
G1 (Garbage-First) GC — pengumpul default di Java 9+. Heap dibagi menjadi region 1–32 MB. G1 memprediksi waktu jeda dan berusaha untuk tetap dalam batas yang ditentukan (default 200 ms). Prioritas: pertama-tama region dengan volume sampah terbesar dibersihkan (dari situlah namanya). G1 efisien untuk server dengan heap besar (4–64 GB) dan jeda yang dapat diprediksi.
// Mengaktifkan G1 GC dengan target jeda 100 ms
// java -XX:+UseG1GC -XX:MaxGCPauseMillis=100 -jar app.jar
public class MemoryMonitor {
private static final long THRESHOLD = 512 * 1024 * 1024; // 512 MB
public void checkHeapUsage() {
Runtime rt = Runtime.getRuntime();
long used = rt.totalMemory() - rt.freeMemory();
if (used > THRESHOLD) {
System.out.println("Ambang penggunaan heap terlampaui: " + used);
System.out.println("Pertimbangkan untuk mengurangi alokasi");
}
}
}
Pemantauan heap melalui Runtime memungkinkan deteksi dini kebocoran memori. Jika used melebihi 80% dari heap maksimum saat pekerjaan stabil — ini adalah sinyal kemungkinan kebocoran atau konsumsi memori berlebihan oleh aplikasi.
Bahkan ART GC modern tidak menyelesaikan semua masalah — penggunaan memori yang tidak tepat tetap menjadi penyebab utama jank dan ANR (Application Not Responding). Mari kita lihat skenario utama dan metode optimasi.
GC Pauses — penghentian thread aplikasi selama pengumpulan. Di layar, ini muncul sebagai frame yang terlewat, ketika waktu antara dua frame melebihi 16.6 ms (60 FPS). Jika GC berlangsung 30 ms, hanya satu frame yang digambar, bukan dua — pengguna melihat lag antarmuka.
Penyebab utama jeda panjang: banyaknya objek hidup di Old Generation, fragmentasi heap, Full GC yang sering. Untuk diagnostik gunakan Android Studio Profiler dan systrace.
Aturan utama kode ramah GC — minimalkan jumlah objek yang dialokasikan. Setiap objek baru tidak hanya memerlukan alokasi memori, tetapi juga pengumpulan berikutnya. Bahkan jika GC cepat, 1000 alokasi tambahan per detik memberikan 1000 pemeriksaan bagi pengumpul.
Kebocoran memori terjadi ketika suatu objek tetap dapat dijangkau, meskipun tidak lagi diperlukan. GC tidak dapat menghapus objek semacam itu, dan memori secara bertahap habis. Penyebab umum: listener yang tidak dibatalkan pendaftarannya, referensi statis ke Activity, kelas anonim yang menangkap konteks eksternal, dan Cursor/InputStream yang tidak ditutup.
// Kebocoran memori: kelas anonim menyimpan referensi ke Activity
public void startTask() {
new Thread(new Runnable() { // secara implisit menyimpan this (Activity)
@Override
public void run() {
// operasi panjang...
System.out.println("Selesai");
}
}).start();
}
// Perbaikan: kelas statis bersarang + WeakReference
private static class TaskRunnable implements Runnable {
private WeakReference<Activity> activityRef;
TaskRunnable(Activity activity) {
this.activityRef = new WeakReference<>(activity);
}
@Override
public void run() {
Activity act = activityRef.get();
if (act != null) {
// kerja aman dengan Activity
}
}
}
Dalam contoh ini, Runnable anonim menangkap referensi implisit ke Activity. Selama thread hidup — Activity tidak dapat dikumpulkan oleh GC, bahkan jika pengguna telah menutup layar. Perbaikan WeakReference + static class memutus rantai ini dan memungkinkan Activity untuk digunakan kembali.
Pertanyaan Umum
GC di Android (ART) adalah pengumpul generasional dengan kompaktifikasi concurrent, dioptimalkan untuk perangkat mobile dengan memori terbatas. Java GC (G1, ZGC) adalah pengumpul server dengan heap besar dan jeda yang dapat diprediksi. ART GC tidak menggunakan flag JVM — semua konfigurasi dilakukan secara otomatis di tingkat OS.
Stop-The-World — momen ketika pengumpul menghentikan semua thread aplikasi untuk menelusuri graf objek dengan aman atau membebaskan memori. Semakin lama STW, semakin terlihat jank-nya. ART mengurangi waktu STW tipikal menjadi 2–4 ms berkat arsitektur generasional.
Gunakan Android Studio Memory Profiler — ini menunjukkan pertumbuhan heap, jumlah alokasi dan memungkinkan Heap Dump. Untuk analisis mendalam, gunakan LeakCanary — perpustakaan secara otomatis mendeteksi kebocoran dan menunjukkan rantai referensi yang menghalangi pengumpulan GC.
Full GC — pengumpulan lengkap semua generasi heap, termasuk Old Generation. Di aplikasi mobile, Full GC dapat berlangsung 50–200 ms, menyebabkan jank yang terlihat atau ANR. Penyebab utama: fragmentasi heap, kebocoran memori, melampaui ambang batas Old Generation.
Kotlin menyediakan coroutine dengan konkurensi terstruktur — pembatalan scope secara otomatis membatalkan semua coroutine anak, mencegah kebocoran. Juga di Kotlin ada delegat lazy untuk inisialisasi malas dan operator lingkup yang mengurangi jumlah objek sementara.
Kesimpulan
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