Mengelola memori aplikasi

Halaman ini menjelaskan cara mengurangi penggunaan memori dalam aplikasi Anda secara proaktif. Untuk mengetahui informasi tentang cara sistem operasi Android mengelola memori, lihat Ringkasan pengelolaan memori.

Random access memory (RAM) merupakan resource berharga untuk setiap lingkungan pengembangan software, terlebih pada sistem operasi seluler yang sering dibatasi oleh memori fisik. Meskipun Android Runtime (ART) dan mesin virtual Dalvik menjalankan pembersihan sampah memori secara rutin, hal ini tidak berarti Anda dapat mengabaikan kapan dan di mana aplikasi Anda mengalokasikan dan melepaskan memori. Anda tetap perlu menghindari timbulnya kebocoran memori, yang biasanya disebabkan oleh penahanan referensi objek dalam variabel anggota statis, dan melepaskan objek Reference pada waktu yang tepat seperti ditetapkan oleh callback siklus proses.

Mengurangi jejak kode dan resource aplikasi Anda

Beberapa resource dan library dalam kode Anda dapat menghabiskan memori tanpa Anda sadari. Ukuran keseluruhan aplikasi, termasuk library pihak ketiga atau resource tersemat, dapat memengaruhi jumlah memori yang digunakan aplikasi Anda. Anda dapat memperbaiki konsumsi memori aplikasi dengan menghapus komponen, resource, dan library yang berlebihan, tidak perlu, atau membengkak dari kode Anda.

Mengurangi ukuran aplikasi secara keseluruhan dengan mengaktifkan R8

Kode aplikasi yang dikompilasi adalah bagian aktif dari jejak memori runtime Anda. Setiap class, metode, dependensi library, dan konstanta string harus dimuat ke dalam RAM saat dijalankan. Makin besar codebase yang dikompilasi, makin banyak RAM fisik yang dibutuhkan aplikasi Anda untuk ada.

Anda dapat menggunakan R8 untuk mengurangi jejak memori aplikasi Anda. Meskipun R8 biasanya dikenal untuk mengecilkan ukuran APK, R8 memiliki dampak positif langsung pada memori runtime (RAM). R8 menganalisis bytecode aplikasi Anda untuk menghapus kode yang tidak digunakan, menggabungkan class yang berlebihan, menyisipkan metode, dan meminimalkan ID. Dengan memuat lebih sedikit bytecode yang dikompilasi dari APK ke dalam RAM, jejak memori dasar aplikasi secara keseluruhan akan berkurang. Selain itu, meminimalkan nama class, metode, dan bidang menjadi ID yang lebih pendek secara langsung mengurangi overhead RAM. Pengoptimalan seperti penggabungan class dan inline metode yang ekstensif juga menggantikan pola alokasi dan pencarian runtime yang mahal, sehingga menghasilkan memori heap dan stack yang dioptimalkan.

Memahami aturan penyimpanan

Aturan keep adalah petunjuk konfigurasi yang memberi tahu R8 bagian kode mana yang harus dipertahankan selama pengoptimalan, sehingga mencegahnya menghapus atau meminifikasi kode yang diandalkan aplikasi Anda. Untuk mengetahui informasi selengkapnya, lihat Ringkasan aturan penyimpanan.

Aturan keep yang ditulis dengan buruk mencegah R8 mengoptimalkan sebagian besar codebase Anda. Hindari aturan penyimpanan yang terlalu luas dan ikuti praktik terbaik berikut:

  • Aturan global yang harus dihindari:
    • -dontoptimize: Menonaktifkan pengoptimalan sepenuhnya untuk seluruh aplikasi, sehingga menghasilkan file yang lebih besar dan lebih lambat.
    • -dontshrink: Mencegah penghapusan kode dan resource yang tidak digunakan.
    • -dontobfuscate: Mencegah minifikasi nama, sehingga tidak mendapatkan penghematan memori yang berharga (terutama di aplikasi besar).
  • Hindari karakter pengganti di seluruh paket: Aturan luas seperti -keep class com.example.package.** { *; } memaksa R8 untuk mempertahankan setiap class, kolom, dan metode dalam paket tersebut. Hal ini akan sepenuhnya menghentikan kemampuan R8 untuk menghapus, mengoptimalkan, atau mengecilkan kode dalam paket tersebut.

  • Gunakan file konfigurasi R8 default: Selalu gunakan proguard-android-optimize.txt.

Untuk mengetahui informasi selengkapnya tentang cara menulis aturan penyimpanan, lihat Ringkasan aturan penyimpanan. Untuk mengetahui pola spesifik yang harus digunakan dan dihindari, lihat Praktik terbaik aturan penyimpanan.

Penganalisis Konfigurasi R8 memberikan insight tentang konfigurasi R8 Anda dan pengaruh setiap aturan keep terhadap aplikasi Anda. Untuk mengetahui informasi selengkapnya tentang cara mengidentifikasi aturan yang memblokir pengoptimalan, lihat Penganalisis Konfigurasi R8.

Hati-hati saat menggunakan library eksternal

Kode library eksternal sering kali tidak ditulis untuk lingkungan seluler dan dapat menjadi tidak efisien saat digunakan untuk bekerja pada klien seluler. Saat menggunakan library eksternal, Anda mungkin perlu mengoptimalkan library tersebut untuk perangkat seluler. Rencanakan pekerjaan ini sebelumnya dan analisis library dalam hal ukuran kode dan jejak RAM sebelum menggunakannya.

Bahkan beberapa library yang dioptimalkan untuk lingkungan seluler pun dapat menyebabkan masalah karena implementasinya yang berbeda. Misalnya, satu library mungkin menggunakan lite protobuf sementara library lain menggunakan micro protobuf, sehingga terdapat dua implementasi protobuf berbeda dalam aplikasi Anda. Hal ini dapat terjadi dengan berbagai implementasi logging, analitik, framework pemuatan gambar, penyimpanan cache, dan berbagai hal lainnya yang tidak Anda harapkan.

Meskipun mengoptimalkan aplikasi menggunakan R8 dapat menghapus kode yang tidak digunakan dari dependensi, efektivitasnya sering kali dibatasi oleh konfigurasi internal library. Misalnya, aturan keep yang luas atau penggunaan refleksi dalam library dapat mencegah R8 menyusutkan kodenya, sehingga menghasilkan footprint memori yang lebih besar. Untuk mengetahui strategi dalam memilih library yang efisien, lihat Pilih library dengan bijak.

Selain itu, hindari menggunakan library bersama untuk hanya satu atau dua fitur dari lusinan fitur lainnya. Jangan menarik sejumlah besar kode dan overhead yang tidak Anda gunakan. Saat Anda mempertimbangkan apakah akan menggunakan library, cari implementasi yang sangat cocok dengan kebutuhan Anda. Jika tidak, Anda mungkin perlu membuat implementasi Anda sendiri.

Menggunakan Hilt atau Dagger 2 untuk injeksi dependensi

Framework injeksi dependensi dapat menyederhanakan kode yang Anda tulis dan memberikan lingkungan adaptif yang berguna untuk pengujian dan perubahan konfigurasi lainnya.

Jika Anda ingin menggunakan framework injeksi dependensi di aplikasi Anda, pertimbangkan untuk menggunakan Hilt atau Dagger. Hilt adalah library injeksi dependensi untuk Android yang berjalan di atas Dagger. Dagger tidak menggunakan refleksi untuk memindai kode aplikasi Anda. Anda dapat menggunakan implementasi waktu kompilasi statis Dagger di aplikasi Android tanpa biaya runtime atau penggunaan memori yang tidak perlu.

Framework injeksi dependensi lain yang menggunakan refleksi menginisialisasi proses dengan memindai kode untuk menemukan anotasi. Proses ini dapat memerlukan siklus CPU dan RAM yang jauh lebih banyak, dan dapat menyebabkan keterlambatan yang kentara saat aplikasi diluncurkan.

Saat menggunakan injeksi dependensi, berhati-hatilah agar tidak terjadi kebocoran memori dengan memastikan bahwa objek dicakup dengan tepat. Mempertahankan objek lebih lama dari yang diperlukan dengan mengikatnya ke siklus proses yang salah dapat menyebabkan kebocoran memori. Untuk informasi selengkapnya, lihat panduan tentang menghindari kebocoran memori dengan objek bercakupan.

Memuat gambar dengan sengaja

Bitmap grafis biasanya merupakan objek umum terbesar yang berada di memori aplikasi Anda. Meskipun Anda bekerja dengan file terkompresi seperti JPEG, file harus dikembangkan menjadi bitmap yang tidak dikompresi untuk ditampilkan di layar. File gambar terkompresi berukuran kecil dapat diperluas menjadi bitmap yang sangat besar.

Misalnya, sebagian besar bitmap menggunakan konfigurasi ARGB_8888, yang berarti setiap piksel memerlukan memori 4 byte--masing-masing satu byte untuk merah, hijau, biru, dan alfa (transparansi). Jika Anda memiliki JPEG 100 KB dan menampilkannya dalam tampilan 1000×1000 piksel, bitmap akan memerlukan 4 byte untuk setiap 1.000.000 piksel tersebut, sehingga menambah hingga 4 MB memori.

Ada beberapa hal yang dapat Anda lakukan untuk mengoptimalkan penggunaan gambar. Misalnya, menggunakan library pemuatan gambar dapat membantu Anda melepaskan memori saat tidak diperlukan. Untuk mengetahui informasi tentang cara menangani gambar secara efisien, lihat Mengoptimalkan gambar bitmap.

Memantau memori yang tersedia dan penggunaan memori

Anda harus menemukan masalah penggunaan memori aplikasi sebelum dapat memperbaikinya. Profiler memori Android Studio membantu Anda menemukan dan mendiagnosis masalah memori melalui cara berikut:

Profiler memori juga terintegrasi dengan library deteksi kebocoran LeakCanary. Dengan menggunakan LeakCanary, Anda dapat memindahkan analisis kebocoran memori dari perangkat pengujian ke mesin pengembangan, yang dapat mempercepat alur kerja Anda secara signifikan. Untuk mengetahui informasi selengkapnya, lihat catatan rilis Android Studio.

Ada alat lain yang dapat Anda gunakan untuk mendiagnosis masalah memori berdasarkan data dari pengguna yang menjalankan aplikasi produksi Anda:

Melepaskan memori sebagai respons terhadap peristiwa

Android dapat memperoleh kembali memori dari aplikasi Anda atau menghentikan aplikasi sepenuhnya jika diperlukan untuk mengosongkan memori untuk tugas penting, seperti yang dijelaskan dalam Ringkasan pengelolaan memori. Untuk menyeimbangkan memori sistem lebih jauh lagi dan menghindari penghentian proses aplikasi oleh sistem, Anda dapat mengimplementasikan antarmuka ComponentCallbacks2 dalam class Activity. Metode callback onTrimMemory() yang disediakan memberi tahu aplikasi Anda tentang peristiwa siklus proses atau terkait memori yang memberikan peluang baik bagi aplikasi Anda untuk mengurangi penggunaan memori secara sukarela. Mengosongkan memori dapat mengurangi frekuensi aplikasi Anda dihentikan oleh low-memory killer.

Penerapan onTrimMemory() harus berfokus secara eksklusif pada peristiwa TRIM_MEMORY_UI_HIDDEN dan TRIM_MEMORY_BACKGROUND. (Mulai Android 14, sistem tidak lagi mengirimkan notifikasi untuk konstanta lama lainnya. Konstanta tersebut secara resmi tidak digunakan lagi di Android 15.)

  • TRIM_MEMORY_UI_HIDDEN: Sinyal ini menunjukkan bahwa UI aplikasi Anda telah beralih keluar dari tampilan pengguna. Transisi ini memberikan peluang untuk melepaskan alokasi memori yang besar yang terkait secara ketat dengan UI, seperti bitmap, buffer pemutaran video, atau resource animasi yang kompleks.

  • TRIM_MEMORY_BACKGROUND: Sinyal ini menunjukkan bahwa proses Anda berada di latar belakang dan sekarang menjadi kandidat untuk dihentikan guna memenuhi kebutuhan memori global sistem. Untuk memperpanjang durasi proses Anda tetap dalam status yang di-cache, dan mengurangi jumlah cold start aplikasi, Anda harus melepaskan semua resource secara agresif yang dapat dengan mudah direkonstruksi setelah pengguna melanjutkan sesi mereka.

Contoh kode ini menunjukkan cara mengimplementasikan callback onTrimMemory() untuk merespons berbagai peristiwa terkait memori:

Kotlin

import android.content.ComponentCallbacks2
// Other import statements.

class MainActivity : AppCompatActivity(), ComponentCallbacks2 {

    // Other activity code.

    /**
     * Release memory when the UI becomes hidden or when system resources become low.
     * @param level the memory-related event that is raised.
     */
    override fun onTrimMemory(level: Int) {

        if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
            // Release memory related to UI elements, such as bitmap caches.
        }

        if (level >= ComponentCallbacks2.TRIM_MEMORY_BACKGROUND) {
            // Release memory related to background processing, such as by
            // closing a database connection.
        }
    }
}

Java

import android.content.ComponentCallbacks2;
// Other import statements.

public class MainActivity extends AppCompatActivity
    implements ComponentCallbacks2 {

    // Other activity code.

    /**
     * Release memory when the UI becomes hidden or when system resources become low.
     * @param level the memory-related event that is raised.
     */
    public void onTrimMemory(int level) {

        if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
            // Release memory related to UI elements, such as bitmap caches.
        }

        if (level >= ComponentCallbacks2.TRIM_MEMORY_BACKGROUND) {
            // Release memory related to background processing, such as by
            // closing a database connection.
        }
    }
}

Memeriksa jumlah memori yang Anda perlukan

Agar beberapa proses dapat berjalan sekaligus, Android menetapkan batas pasti ukuran heap yang dialokasikan untuk setiap aplikasi. Batas ukuran heap yang pasti ini bervariasi antarperangkat, tergantung banyaknya RAM yang dimiliki perangkat secara keseluruhan. Jika aplikasi Anda mencapai kapasitas heap dan mencoba mengalokasikan lebih banyak memori, sistem akan menampilkan OutOfMemoryError.

Untuk menghindari kehabisan memori, Anda dapat mengkueri sistem untuk mengetahui banyaknya ruang heap yang tersedia di perangkat saat ini. Anda dapat mengkueri angka ini dari sistem dengan memanggil getMemoryInfo(). Tindakan ini menampilkan objek ActivityManager.MemoryInfo yang memberikan informasi tentang status memori saat ini pada perangkat, termasuk memori yang tersedia, memori total, dan ambang batas memori—tingkat memori di mana sistem akan mulai menghentikan proses. Objek ActivityManager.MemoryInfo juga mengekspos lowMemory, yang merupakan boolean sederhana yang memberi tahu Anda apakah perangkat kehabisan memori.

Contoh cuplikan kode berikut menunjukkan cara menggunakan metode getMemoryInfo() di aplikasi Anda.

Kotlin

fun doSomethingMemoryIntensive() {

    // Before doing something that requires a lot of memory,
    // check whether the device is in a low memory state.
    if (!getAvailableMemory().lowMemory) {
        // Do memory intensive work.
    }
}

// Get a MemoryInfo object for the device's current memory status.
private fun getAvailableMemory(): ActivityManager.MemoryInfo {
    val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
    return ActivityManager.MemoryInfo().also { memoryInfo ->
        activityManager.getMemoryInfo(memoryInfo)
    }
}

Java

public void doSomethingMemoryIntensive() {

    // Before doing something that requires a lot of memory,
    // check whether the device is in a low memory state.
    ActivityManager.MemoryInfo memoryInfo = getAvailableMemory();

    if (!memoryInfo.lowMemory) {
        // Do memory intensive work.
    }
}

// Get a MemoryInfo object for the device's current memory status.
private ActivityManager.MemoryInfo getAvailableMemory() {
    ActivityManager activityManager = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
    ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
    activityManager.getMemoryInfo(memoryInfo);
    return memoryInfo;
}

Memantau penghentian karena memori rendah

Low-memory kill (LMK) yang terlihat oleh pengguna terjadi saat memori sistem sangat menipis. Saat memori hampir penuh, lmkd (daemon penghentian proses karena memori hampir penuh) akan menghentikan proses berdasarkan oom_adj_score-nya. Aplikasi yang di-cache, atau menjalankan layanan tanpa UI terkait (seperti tugas), memiliki skor tertinggi dan dihentikan terlebih dahulu. Jika memori tetap sangat rendah, daemon akan dipaksa untuk merebut kembali memori dari proses dengan oom_adj_score 0. Karena skor tersebut dicadangkan untuk aplikasi yang terlihat, penghentiannya akan menyebabkan keluar dari proses yang tidak lancar dan langsung. Bagi pengguna akhir, aplikasi tampak error, sering kali melewati mekanisme penyimpanan status siklus proses standar dan mengakibatkan hilangnya progres pengguna.

Penghentian proses latar depan menjadi fokus utama di Android Vitals karena proses tersebut berfungsi sebagai proksi dengan keakuratan tinggi untuk salah pengelolaan memori. Meskipun rasio LMK yang lebih tinggi dari 1% menunjukkan kebutuhan mendesak untuk segera mengambil tindakan, rasio yang rendah tidak selalu merupakan indikator kesehatan. Rasio LMK yang dirasakan pengguna yang rendah mungkin berarti daemon LMK sering menghentikan proses saat berada di latar belakang, yang menurunkan performa "start-up hangat" dan kelancaran multitasking. Oleh karena itu, sebaiknya ikuti praktik terbaik memori terlepas dari skor LMK Anda saat ini, untuk memastikan stabilitas jangka panjang dan kesehatan perangkat.

Menggunakan ProfilingManager untuk melacak masalah memori

Platform Android menyediakan ProfilingManager, API pengamatan lanjutan yang memungkinkan Anda merekam data pengguna dalam produksi berdasarkan pemicu yang Anda tetapkan. Tindakan ini dapat membantu Anda mengidentifikasi masalah memori yang sulit direproduksi.

Dua pemicu baru yang diperkenalkan dengan Android 17 sangat berguna untuk mendeteksi masalah memori:

  • TRIGGER_TYPE_OOM menunjukkan bahwa aplikasi telah memunculkan OutOfMemoryError. Hal ini dipicu pada saat aplikasi berikutnya dimulai setelah error, saat aplikasi mendaftar untuk pemicu pembuatan profil.
  • TRIGGER_TYPE_ANOMALY dipicu saat sistem mendeteksi perilaku anomali dari aplikasi. Selain hal lainnya, hal ini dapat dipicu oleh penggunaan memori yang berlebihan. Peringatan ini dipicu setelah aplikasi menunjukkan penggunaan memori yang berlebihan, dan sebelum sistem melakukan tindakan apa pun untuk menghentikan proses yang bermasalah. Misalnya, jika aplikasi melebihi batas memori yang diperkenalkan di Android 17, TRIGGER_TYPE_ANOMALY akan dipicu sebelum sistem menghentikan aplikasi.

Untuk mengetahui informasi selengkapnya tentang penggunaan ProfilingManager untuk mendaftarkan dan mengambil pemicu secara terprogram, lihat dokumentasi pembuatan profil berbasis pemicu.

Anda juga dapat menggunakan pembuatan profil yang didorong aplikasi untuk menentukan titik awal dan akhir pelacakan secara manual. Sebaiknya lakukan hal ini untuk mengambil dump heap atau profil heap secara manual di area yang Anda duga mungkin mengalami kebocoran memori atau penggunaan memori yang berlebihan.

Menggunakan konstruksi kode yang lebih hemat-memori

Beberapa fitur Android, class Java, dan konstruksi kode menggunakan lebih banyak memori dibandingkan yang lain. Anda dapat meminimalkan banyaknya memori yang digunakan aplikasi dengan memilih alternatif yang lebih efisien dalam kode Anda.

Menggunakan layanan seperlunya

Sebaiknya jangan biarkan layanan berjalan jika tidak diperlukan. Membiarkan layanan yang tidak perlu tetap berjalan adalah salah satu kesalahan pengelolaan memori terburuk yang dapat dilakukan aplikasi Android. Jika aplikasi Anda memerlukan layanan untuk bekerja di latar belakang, jangan biarkan layanan tersebut terus berjalan kecuali jika diperlukan untuk menjalankan tugas. Hentikan layanan Anda saat layanan tersebut menyelesaikan tugasnya. Jika tidak, Anda berisiko menimbulkan kebocoran memori.

Saat Anda memulai layanan, sistem lebih suka mempertahankan agar proses untuk layanan tersebut selalu berjalan. Perilaku ini membuat proses layanan menjadi sangat tidak efisien karena RAM yang digunakan oleh layanan menjadi tidak tersedia untuk proses lainnya. Keadaan ini mengurangi jumlah proses yang di-cache yang dapat dipertahankan sistem dalam cache LRU, sehingga peralihan aplikasi menjadi kurang efisien. Selain itu, tindakan ini dapat membebani sistem saat memori yang tersedia sangat terbatas dan sistem tidak dapat mempertahankan cukup proses untuk meng-hosting semua layanan yang sedang berjalan.

Secara umum, hindari penggunaan layanan persisten karena jenis layanan ini terus-menerus membebani memori yang tersedia. Sebagai gantinya, sebaiknya gunakan implementasi alternatif, seperti WorkManager. Untuk mengetahui informasi selengkapnya tentang cara menggunakan WorkManager untuk menjadwalkan proses latar belakang, lihat Pekerjaan persisten.

Menggunakan container data yang dioptimalkan

Beberapa class yang disediakan oleh bahasa pemrograman tidak dioptimalkan untuk penggunaan pada perangkat seluler. Misalnya, implementasi HashMap generik bisa sangat menguras memori karena memerlukan objek entri tersendiri untuk setiap pemetaan.

Framework Android mencakup beberapa penampung data yang dioptimalkan, termasuk SparseArray, SparseBooleanArray, dan LongSparseArray. Misalnya, class SparseArray lebih efisien karena dapat mencegah perlunya sistem melakukan autobox pada kunci dan terkadang nilai, yang membuat satu objek lagi atau dua objek per entri.

Jika perlu, Anda dapat beralih ke array mentah kapan saja untuk menggunakan struktur data yang benar-benar ramping.

Hati-hati dengan abstraksi kode

Developer sering menggunakan abstraksi sebagai praktik pemrograman yang baik karena dapat meningkatkan fleksibilitas dan pemeliharaan kode. Namun, abstraksi umumnya memerlukan lebih banyak kode untuk dieksekusi. Seperti yang dijelaskan dalam Mengurangi jejak kode dan resource aplikasi Anda, codebase yang dikompilasi lebih besar secara langsung akan meningkatkan RAM fisik yang diperlukan aplikasi Anda. Jika abstraksi Anda tidak memberikan manfaat secara signifikan, hindari abstraksi.

Menggunakan lite protobuf untuk data serial

Buffering protokol (protobuf) adalah mekanisme yang tidak tergantung bahasa, tidak tergantung platform, dan dapat diperluas yang dirancang Google untuk membuat serialisasi data terstruktur—mirip dengan XML, tetapi lebih kecil, lebih cepat, dan lebih sederhana. Jika menggunakan protobuf untuk data Anda, selalu gunakan lite protobuf dalam kode sisi klien. Protobuf reguler menghasilkan kode yang sangat panjang, yang meningkatkan jejak kode aplikasi Anda di RAM (lihat Mengelola dan mengoptimalkan jejak kode aplikasi Anda) dan berkontribusi pada peningkatan ukuran APK.

Untuk mengetahui informasi selengkapnya, lihat readme protobuf.

Berhati-hatilah terhadap kebocoran memori

Pengelolaan referensi yang tidak tepat dapat menyebabkan kebocoran memori saat objek bertahan lebih lama dari masa pakainya yang berguna, sehingga mencegah pembersih sampah memori mengklaim kembali memori objek yang bocor. Untuk menghindari kebocoran memori, terapkan desain yang kompatibel dengan siklus proses.

Untuk mengetahui informasi selengkapnya, lihat Kebocoran memori.

Menghindari churn memori

Peristiwa pembersihan sampah memori tidak memengaruhi performa aplikasi. Namun, banyaknya peristiwa pembersihan sampah memori yang terjadi dalam waktu singkat dapat dengan cepat menghabiskan daya baterai serta sedikit meningkatkan waktu untuk menyiapkan frame karena interaksi yang diperlukan antara pembersih sampah memori dan thread aplikasi. Makin banyak waktu yang dihabiskan sistem untuk pembersihan sampah memori, makin cepat daya baterai habis.

Sering kali, churn memori dapat menyebabkan terjadinya sejumlah besar peristiwa pembersihan sampah memori. Dalam praktiknya, churn memori menunjukkan jumlah pengalokasian objek sementara yang terjadi dalam rentang waktu tertentu.

Misalnya, Anda dapat mengalokasikan beberapa objek sementara dalam loop for. Atau, Anda dapat membuat objek Paint atau Bitmap baru di dalam fungsi onDraw() tampilan. Dalam kedua kasus ini, aplikasi akan membuat banyak objek dengan cepat pada volume tinggi. Hal ini dapat menghabiskan semua memori yang tersedia dengan cepat di generasi muda, sehingga memaksa terjadinya peristiwa pembersihan sampah memori.

Gunakan Memory Profiler untuk menemukan tempat dalam kode dengan churn memori yang tinggi agar Anda dapat memperbaikinya.

Setelah mengidentifikasi area masalah dalam kode Anda, cobalah untuk mengurangi jumlah alokasi dalam area yang kritis performa. Pertimbangkan untuk mengeluarkan objek dari loop dalam, atau mungkin memindahkannya ke dalam struktur alokasi berbasis factory.

Anda juga dapat mengevaluasi apakah kumpulan objek menguntungkan kasus penggunaan. Dengan kumpulan objek, alih-alih melepaskan instance objek ke lantai, Anda akan melepaskannya ke dalam kumpulan setelah tidak diperlukan lagi. Saat berikutnya instance objek dari jenis tersebut diperlukan, Anda dapat memperolehnya dari kumpulan, bukan mengalokasikannya.

Evaluasi performa secara menyeluruh untuk menentukan apakah kumpulan objek cocok dalam situasi tertentu. Ada kalanya kumpulan objek dapat memperburuk performa. Meskipun menghindari alokasi, kumpulan tersebut menimbulkan overhead lain. Misalnya, mempertahankan kumpulan biasanya melibatkan sinkronisasi, yang memiliki overhead yang tidak dapat diabaikan. Selain itu, menghapus instance objek gabungan untuk menghindari kebocoran memori selama rilis, lalu inisialisasinya selama akuisisi dapat menimbulkan overhead yang bukan nol.

Menahan lebih banyak instance objek di dalam kumpulan daripada yang diperlukan juga dapat membebani pembersihan sampah memori. Meskipun kumpulan objek mengurangi jumlah pemanggilan pengumpulan sampah, kumpulan objek tersebut pada akhirnya meningkatkan jumlah pekerjaan yang diperlukan untuk setiap pemanggilan, karena ini sebanding dengan jumlah byte aktif (yang dapat dijangkau).