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
Beberapa resource dan library dalam kode Anda bisa 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 diperlukan aplikasi Anda.
Anda dapat menggunakan R8 untuk mengurangi jejak memori aplikasi. Meskipun R8 secara tradisional dikenal untuk mengurangi 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, metode inline, dan meng-minify ID. Dengan memuat lebih sedikit bytecode yang dikompilasi dari APK ke dalam RAM, jejak memori dasar aplikasi secara keseluruhan akan berkurang. Selain itu, meng-minify nama class, metode, dan kolom menjadi ID yang lebih pendek akan langsung mengurangi overhead RAM. Pengoptimalan seperti penggabungan class dan metode inline yang ekstensif juga menggantikan pola pencarian dan alokasi runtime yang mahal, sehingga menghasilkan memori heap dan stack yang dioptimalkan.
Memahami aturan keep
Aturan keep adalah petunjuk konfigurasi yang memberi tahu R8 bagian kode mana yang harus dipertahankan selama pengoptimalan, sehingga mencegahnya menghapus atau meng-minify kode yang digunakan aplikasi Anda. Untuk mengetahui informasi selengkapnya, lihat Ringkasan aturan keep.
Aturan keep yang ditulis dengan buruk akan mencegah R8 mengoptimalkan sebagian besar codebase Anda. Hindari aturan keep yang terlalu luas dan ikuti praktik terbaik berikut:
- Aturan global yang harus dihindari:
-dontoptimize: Sepenuhnya menonaktifkan pengoptimalan untuk seluruh aplikasi, sehingga menghasilkan file yang dapat dieksekusi yang lebih besar dan lebih lambat.-dontshrink: Mencegah penghapusan kode dan resource yang tidak digunakan.-dontobfuscate: Mencegah minifikasi nama, sehingga kehilangan 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 sepenuhnya menghentikan kemampuan R8 untuk menghapus, mengoptimalkan, atau meng-minify kode dalam paket tersebut.Gunakan file konfigurasi R8 default: Selalu gunakan
proguard-android-optimize.txt.
Untuk mengetahui informasi selengkapnya tentang cara menulis aturan keep, lihat Ringkasan aturan keep. Untuk mengetahui pola tertentu yang harus digunakan dan dihindari, lihat Praktik terbaik aturan keep.
Configuration Analyzer R8 memberikan insight tentang konfigurasi R8 dan pengaruh setiap aturan keep terhadap aplikasi Anda. Untuk mengetahui informasi selengkapnya tentang cara mengidentifikasi aturan yang memblokir pengoptimalan, lihat Configuration Analyzer 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 mengoptimalkannya 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, yang menghasilkan dua implementasi protobuf yang berbeda di aplikasi Anda. Hal ini dapat terjadi dengan berbagai implementasi logging, analisis, 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 mengurangi kode, sehingga menyebabkan jejak memori yang lebih besar. Untuk mengetahui strategi memilih library yang efisien, lihat Memilih 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 mempertimbangkan apakah akan menggunakan library, temukan implementasi yang benar-benar 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 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 untuk menghindari kebocoran memori dengan memastikan objek diberi cakupan yang sesuai. Mempertahankan objek lebih lama dari yang diperlukan dengan mengikatnya ke siklus proses yang salah dapat menyebabkan kebocoran memori.
Berhati-hati saat memuat gambar
Bitmap grafis biasanya merupakan objek umum terbesar yang berada di memori aplikasi Anda. Meskipun Anda menggunakan file terkompresi seperti JPEG, file tersebut harus di-inflate menjadi bitmap yang tidak terkompresi agar dapat ditampilkan di layar. File gambar terkompresi kecil dapat diperluas menjadi bitmap yang sangat besar.
Misalnya, sebagian besar bitmap menggunakan konfigurasi ARGB_8888, yang berarti setiap piksel memerlukan memori 4 byte—satu byte untuk merah, hijau, biru, dan alfa (transparansi). Jika Anda memiliki JPEG 100 KB dan menampilkannya dalam tampilan piksel 1000×1000, bitmap akan memerlukan 4 byte untuk setiap 1.000.000 piksel tersebut, sehingga totalnya mencapai 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. Memory profiler Android Studio membantu Anda menemukan dan mendiagnosis masalah memori melalui cara berikut:
- Lihat bagaimana aplikasi Anda mengalokasikan memori dari waktu ke waktu. Memory profiler menampilkan grafik real time yang menunjukkan banyaknya memori yang digunakan aplikasi Anda, jumlah objek Java yang dialokasikan, dan kapan pembersihan sampah memori dilakukan.
- Mulai peristiwa pembersihan sampah memori dan ambil cuplikan dari heap Java selagi aplikasi berjalan.
- Rekam alokasi memori aplikasi Anda, lalu periksa semua objek yang dialokasikan, lihat stack trace untuk setiap alokasi, dan beralihlah ke kode yang sesuai pada editor Android Studio.
Memory profiler 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:
- Gunakan Android Vitals untuk melacak peristiwa low memory kill (LMK).
- Gunakan Profiling Manager untuk melacak error kehabisan memori, serta perilaku aplikasi anomali yang mungkin disebabkan oleh kebocoran memori.
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 secara maksimal dan menghindari penghentian proses aplikasi oleh sistem, Anda dapat mengimplementasikan antarmuka ComponentCallbacks2
dalam class Activity. Metode callback yang disediakan akan memberi tahu aplikasi Anda tentang peristiwa siklus proses atau terkait memori yang memberikan peluang baik bagi aplikasi Anda untuk secara sukarela mengurangi penggunaan memorinya.onTrimMemory()
Mengosongkan memori dapat mengurangi frekuensi aplikasi Anda dihentikan oleh
low-memory killer.
Implementasi onTrimMemory() Anda 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 bertransisi keluar dari tampilan pengguna. Transisi ini memberikan peluang untuk melepaskan alokasi memori substansial yang terikat secara ketat ke 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 secara agresif melepaskan resource apa pun yang dapat direkonstruksi dengan mudah setelah pengguna melanjutkan sesi.
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 Anda miliki pada perangkat saat ini. Untuk mengetahui angkanya, panggil getMemoryInfo(). Tindakan ini mengembalikan 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 yang mana sistem akan mulai mengakhiri
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 low memory kill
Low memory kill (LMK) yang terlihat oleh pengguna terjadi saat memori sistem menjadi sangat rendah. Saat memori rendah, lmkd (daemon low memory killer
) akan menghentikan proses berdasarkan oom_adj_score. 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 mendapatkan kembali memori dari proses dengan oom_adj_score 0.
Karena skor tersebut dicadangkan untuk aplikasi yang terlihat, penghentiannya akan menghasilkan proses keluar yang langsung dan tidak lancar. Bagi pengguna akhir, aplikasi terlihat error, sering kali melewati mekanisme penyimpanan status siklus proses standar dan mengakibatkan hilangnya progres pengguna.
Penghentian proses latar depan adalah fokus utama di Android Vitals karena berfungsi sebagai proxy fidelitas tinggi untuk kesalahan pengelolaan memori. Meskipun setiap rasio LMK yang lebih tinggi dari 1% menunjukkan kebutuhan mendesak untuk tindakan segera, rasio yang rendah tidak selalu merupakan indikator kesehatan. Rasio LMK yang dirasakan pengguna yang rendah mungkin berarti bahwa daemon LMK sering menghentikan proses saat berada di latar belakang, yang menurunkan performa "warm start" dan fluiditas multitasking. Oleh karena itu, sebaiknya patuhi 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 observabilitas
lanjutan yang memungkinkan Anda mengambil data pengguna dalam produksi berdasarkan
pemicu yang Anda tetapkan. Melakukan hal ini dapat membantu Anda mengidentifikasi masalah memori yang sulit direproduksi.
Dua pemicu baru yang diperkenalkan dengan Android 17 sangat berguna untuk menemukan masalah memori:
TRIGGER_TYPE_OOMmenunjukkan bahwa aplikasi telah menampilkanOutOfMemoryError. Pemicu ini akan dipicu saat aplikasi dimulai setelah error, saat aplikasi mendaftar untuk pemicu pembuatan profil.TRIGGER_TYPE_ANOMALYdipicu saat sistem mendeteksi perilaku anomali dari aplikasi. Selain hal lainnya, hal ini dapat dipicu oleh penggunaan memori yang berlebihan. Pemicu ini akan dipicu setelah aplikasi menunjukkan penggunaan memori yang berlebihan, dan sebelum sistem mengambil tindakan apa pun untuk menghentikan proses yang melanggar. Misalnya, jika aplikasi melebihi batas memori yang diperkenalkan di Android 17,TRIGGER_TYPE_ANOMALYdipicu sebelum sistem menghentikan aplikasi.
Untuk mengetahui informasi selengkapnya tentang cara menggunakan ProfilingManager untuk mendaftarkan
dan mengambil pemicu secara terprogram, lihat dokumentasi pembuatan profil berbasis pemicu.
Anda juga dapat menggunakan pembuatan profil berbasis aplikasi untuk menentukan titik pelacakan awal dan akhir secara manual. Sebaiknya lakukan hal ini untuk mengambil heap dump atau profil heap secara manual di area yang Anda curigai 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 saat layanan telah menyelesaikan tugasnya. Jika tidak, kebocoran memori dapat terjadi.
Saat Anda memulai layanan, sistem lebih suka mempertahankan agar proses untuk layanan tersebut selalu berjalan. Perilaku ini menjadikan proses layanan sangat tidak efisien karena RAM yang digunakan oleh layanan 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, kami merekomendasikan penggunaan implementasi alternatif, seperti WorkManager.
Untuk mengetahui informasi selengkapnya tentang cara menggunakan WorkManager guna 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 generik
HashMap 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, codebase yang dikompilasi lebih besar akan langsung 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 dalam RAM (lihat Mengelola dan mengoptimalkan jejak kode aplikasi) dan berkontribusi pada peningkatan ukuran APK.
Untuk mengetahui informasi selengkapnya, lihat protobuf readme.
Berhati-hati terhadap kebocoran memori
Pengelolaan referensi yang tidak tepat dapat menyebabkan kebocoran memori saat objek melebihi masa pakai yang berguna, sehingga mencegah pembersih sampah memori mendapatkan kembali memori objek yang bocor. Untuk menghindari kebocoran memori, terapkan desain yang memperhatikan siklus proses.
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 data. 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, 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 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 pembersihan sampah memori, kumpulan objek tersebut pada akhirnya meningkatkan jumlah pekerjaan yang diperlukan untuk setiap pemanggilan, karena ini sebanding dengan jumlah byte aktif (yang dapat dijangkau).