Garbage Collection (GC): apa itu, algoritma dan pengumpulan sampah dalam pengembangan mobile

Penulis: IT Sectr Diterbitkan: 2026-03-29 Waktu membaca: 10 mnt

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 — mekanisme otomatis pembebasan memori dengan menghapus objek yang tidak digunakan di Java dan Android
  • Algoritma dasar — Mark-and-Sweep, Copying Collection dan Generational Collection menentukan efisiensi pengumpulan
  • ART dan Dalvik — dua implementasi mesin virtual Android, di mana ART (Android Runtime) menggantikan Dalvik mulai Android 5.0
  • GC Pauses — penghentian eksekusi aplikasi selama pengumpulan — penyebab utama jank dan masalah kinerja
  • Optimasi GC — pengurangan alokasi, penggunaan pool objek dan pemilihan tipe Collection yang tepat mengurangi beban pengumpul

Apa itu Garbage Collection (GC)?

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.

Bagaimana cara kerja pengumpul sampah: algoritma dasar

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

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

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

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.

java
// 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.

Garbage Collection di Android: ART dan Dalvik

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.

KarakteristikDalvik (hingga 4.4)ART (5.0+)
Tipe GCMark-and-Sweep dengan Concurrent MarkGenerasional + Concurrent
Jeda tipikal10–30 ms2–4 ms
KompatifikasiTidak (hanya fragmentasi bertambah)Ya (di latar belakang, tanpa menghentikan aplikasi)
Kompilasi AOTJIT (Just-In-Time)AOT + JIT (hibrida)

Dalvik GC

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 GC

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.

Jenis pengumpul sampah di Java

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

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

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 GC

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.

java
// 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.

Masalah GC dan optimasi memori di aplikasi mobile

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 dan Jank

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.

Mengurangi beban GC

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.

  • Hindari membuat objek dalam loop — tempatkan pembuatan di luar loop, gunakan kembali variabel lokal
  • Gunakan pool objek — untuk Bitmap, byte[] dan struktur berat lainnya, gunakan Object Pool atau RecyclerView.ViewHolder
  • Utamakan primitif — int daripada Integer, float daripada Float menghindari autoboxing
  • Gunakan SparseArray — daripada HashMap<Integer, V>, di Android SDK ada SparseArray, LongSparseArray yang bekerja dengan primitif
  • StringBuilder daripada konkatenasi — setiap penambahan string membuat objek String baru

Kebocoran memori

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.

java
// 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

Apa perbedaan GC di Android dengan GC di Java?

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.

Apa itu Stop-The-World di GC?

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.

Bagaimana cara mendeteksi kebocoran memori di Android?

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.

Kapan Full GC terjadi dan mengapa berbahaya?

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.

Bagaimana Kotlin membantu menghindari kebocoran memori?

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

  • Garbage Collection — manajemen memori otomatis melalui penghapusan objek yang tidak dapat dijangkau, dasar Android Runtime
  • Mark-and-Sweep — algoritma dasar dengan pengumpulan dua fase, menderita fragmentasi heap
  • Copying Collection — menghilangkan fragmentasi dengan menyalin objek hidup ke semi-ruang yang kompak
  • Generational GC — membagi heap menjadi generasi (Young/Old), mempercepat pengumpulan objek muda berumur pendek
  • ART di Android — pengumpul generasional dengan kompaktifikasi concurrent dan jeda 2–4 ms, menggantikan Dalvik di Android 5.0
  • Optimasi GC — pengurangan alokasi, pool objek, primitif daripada wrapper dan SparseArray daripada HashMap mengurangi beban pengumpul
  • Diagnostik — Android Studio Profiler, systrace dan LeakCanary adalah alat utama untuk mengidentifikasi masalah memori

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