Dokumen ini menganggap Anda telah mengikuti panduan praktik terbaik untuk aplikasi Android berdasarkan manajemen memori, seperti Mengelola memori aplikasi.
Pengantar
Kebocoran memori adalah jenis kebocoran resource yang terjadi saat program komputer tidak melepaskan memori yang dialokasikan yang tidak lagi dibutuhkan. Kebocoran dapat menyebabkan aplikasi meminta memori dari OS melebihi yang tersedia, sehingga membuat aplikasi error. Sejumlah praktik yang tidak tepat dapat menyebabkan kebocoran memori di aplikasi Android, seperti tidak membuang resource secara benar atau tidak membatalkan pendaftaran pemroses saat tidak lagi dibutuhkan.
Dokumen ini menguraikan beberapa praktik terbaik kepada Anda untuk membantu mencegah, mendeteksi, dan menyelesaikan masalah kebocoran memori di kode Anda. Jika Anda sudah mencoba semua metode dalam dokumen ini dan menduga ada kebocoran memori di SDK kami, lihat Cara melaporkan masalah terkait SDK Google.
Sebelum menghubungi dukungan
Sebelum Anda melaporkan kebocoran memori kepada tim dukungan Google, ikuti praktik terbaik beserta langkah-langkah proses debug yang diberikan dalam dokumen ini untuk memastikan tidak ada error di kode Anda. Jika tidak berhasil menyelesaikan masalah Anda, langkah-langkah ini dapat memberikan informasi yang dibutuhkan tim dukungan Google untuk membantu Anda.
Mencegah kebocoran memori
Ikuti praktik terbaik ini untuk membantu menghindari beberapa penyebab paling umum kebocoran memori di kode yang menggunakan SDK Google.
Praktik terbaik untuk aplikasi Android
Pastikan Anda telah melakukan semua tindakan berikut di aplikasi Android:
- Melepaskan resource yang tidak digunakan.
- Membatalkan pendaftaran pemroses saat tidak lagi dibutuhkan.
- Membatalkan tugas saat tidak dibutuhkan.
- Meneruskan metode siklus proses untuk melepaskan resource.
- Menggunakan SDK versi terbaru
Untuk mengetahui detail spesifik terkait setiap praktik terbaik ini, lihat bagian berikut.
Melepaskan resource yang tidak digunakan
Saat aplikasi Android Anda menggunakan resource, pastikan untuk melepaskan resource tersebut saat tidak lagi dibutuhkan. Jika tidak dilakukan, resource akan terus mengambil memori bahkan setelah aplikasi Anda tidak lagi menggunakannya. Untuk informasi selengkapnya, tinjau Siklus proses aktivitas di dokumentasi Android.
Merilis referensi GoogleMap yang tidak berlaku di GeoSDK
Kesalahan umum yang sering terjadi adalah GoogleMap dapat menyebabkan kebocoran memori jika di-cache menggunakan NavigationView atau MapView. GoogleMap memiliki hubungan 1:1 dengan NavigationView atau MapView tempat GoogleMap diambil. Anda harus memastikan bahwa GoogleMap tidak di-cache, atau referensi dirilis saat NavigationView#onDestroy atau MapView#onDestroy dipanggil. Jika menggunakan NavigationSupportFragment, MapSupportFragment, atau fragmen Anda sendiri yang menggabungkan tampilan ini, referensi harus dirilis di Fragment#onDestroyView.
class NavFragment : SupportNavigationFragment() {
var googleMap: GoogleMap?
override fun onCreateView(
inflater: LayoutInflater,
parent: ViewGroup?,
savedInstanceState: Bundle?,
): View {
super.onCreateView(inflater,parent,savedInstanceState)
getMapAsync{map -> googleMap = map}
}
override fun onDestroyView() {
googleMap = null
}
}
Membatalkan pendaftaran pemroses saat tidak lagi dibutuhkan
Saat aplikasi Android Anda mendaftarkan pemroses untuk sebuah peristiwa, seperti klik tombol atau perubahan status tampilan, pastikan untuk membatalkan pendaftaran pemroses saat aplikasi tidak perlu lagi memantau peristiwa tersebut. Jika tidak dilakukan, pemroses akan terus mengambil memori bahkan setelah aplikasi Anda tidak lagi menggunakannya.
Misalnya, aplikasi Anda menggunakan Navigation SDK dan memanggil pemroses berikut untuk memproses peristiwa kedatangan: metode
addArrivalListener
untuk memproses peristiwa kedatangan, aplikasi juga akan memanggil removeArrivalListener
saat tidak perlu lagi memantau peristiwa kedatangan.
var arrivalListener: Navigator.ArrivalListener? = null
fun registerNavigationListeners() {
arrivalListener =
Navigator.ArrivalListener {
...
}
navigator.addArrivalListener(arrivalListener)
}
override fun onDestroy() {
navView.onDestroy()
if (arrivalListener != null) {
navigator.removeArrivalListener(arrivalListener)
}
...
super.onDestroy()
}
Membatalkan tugas saat tidak dibutuhkan
Saat aplikasi Android memulai tugas asinkron, seperti download atau permintaan jaringan, pastikan Anda membatalkan tugas tersebut jika sudah selesai. Jika tidak dibatalkan, tugas akan terus berjalan di latar belakang bahkan setelah aplikasi selesai dengan tugas tersebut.
Untuk detail selengkapnya tentang praktik terbaik, lihat Mengelola memori aplikasi di dokumentasi Android.
Meneruskan metode siklus proses untuk melepaskan resource
Jika aplikasi Anda menggunakan Navigation SDK atau Maps SDK, pastikan untuk melepaskan resource dengan meneruskan metode siklus proses (ditampilkan dalam cetak tebal) ke navView
. Anda dapat melakukannya menggunakan NavigationView
di Navigation SDK atau MapView
di Maps SDK atau Navigation SDK. Anda dapat juga menggunakan SupportNavigationFragment
atau
SupportMapFragment
daripada langsung menggunakan NavigationView
dan MapView
. Fragmen dukungan ini menangani penerusan metode siklus proses.
class NavViewActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
navView = ...
navView.onCreate(savedInstanceState)
...
}
override fun onSaveInstanceState(savedInstanceState: Bundle) {
super.onSaveInstanceState(savedInstanceState)
navView.onSaveInstanceState(savedInstanceState)
}
override fun onTrimMemory(level: Int) {
super.onTrimMemory(level)
navView.onTrimMemory(level)
}
/* Same with
override fun onStart()
override fun onResume()
override fun onPause()
override fun onConfigurationChanged(...)
override fun onStop()
override fun onDestroy()
*/
}
Menggunakan SDK versi terbaru
SDK Google terus diupdate dengan fitur baru, perbaikan bug, dan peningkatan performa. Pastikan aplikasi Anda menggunakan SDK versi terbaru agar dapat menerima perbaikan ini.
Men-debug kebocoran memori
Jika masih terjadi kebocoran memori setelah menerapkan semua saran relevan yang diuraikan sebelumnya dalam dokumen ini, ikuti proses ini untuk men-debug.
Sebelum memulai, Anda harus memahami cara Android mengelola memori. Untuk mendapatkan informasi, baca Ringkasan manajemen memori untuk Android.
Untuk men-debug kebocoran memori, ikuti proses berikut:
- Membuat ulang masalah. Langkah ini penting untuk melakukan proses debug pada masalah tersebut.
- Memeriksa apakah penggunaan memori sesuai perkiraan. Pastikan bahwa peningkatan penggunaan yang terlihat seperti kebocoran sebenarnya bukan memori yang diperlukan untuk menjalankan aplikasi Anda.
- Men-debug pada tingkat yang tinggi. Ada beberapa utilitas yang dapat Anda gunakan untuk men-debug. Tiga set alat standar yang berbeda dapat membantu men-debug masalah memori di Android: Android Studio, Perfetto, dan utilitas command line Android Debug Bridge (adb).
- Memeriksa penggunaan memori aplikasi. Dapatkan heap dump dan pelacakan alokasi, lalu lakukan analisis.
- Memperbaiki kebocoran memori.
Bagian berikut akan membahas langkah-langkah ini secara detail.
Langkah 1: Buat ulang masalah
Jika Anda belum dapat membuat ulang masalah tersebut, pertimbangkan dulu skenario yang dapat menyebabkan kebocoran memori. Langsung melihat heap dump mungkin membantu jika Anda tahu masalah tersebut sudah dibuat ulang. Namun, jika Anda baru saja mendapatkan heap dump saat aplikasi dimulai atau pada waktu acak lainnya, Anda mungkin belum mengaktifkan kondisi untuk memicu kebocoran. Pertimbangkan untuk menggunakan berbagai skenario saat mencoba membuat ulang masalah:
Serangkaian fitur apa saja yang diaktifkan?
Urutan tindakan pengguna khusus manakah yang memicu kebocoran?
- Apakah Anda sudah mencoba beberapa iterasi untuk mengaktifkan urutan ini?
Pada kondisi siklus proses manakah aplikasi disikluskan?
- Apakah Anda sudah mencoba beberapa iterasi melalui kondisi siklus proses yang berbeda?
Pastikan Anda dapat membuat ulang masalah di SDK versi terbaru. Masalah dari versi sebelumnya mungkin telah diperbaiki.
Langkah 2: Periksa apakah penggunaan memori untuk aplikasi sesuai perkiraan
Setiap fitur memerlukan memori tambahan. Saat Anda men-debug skenario yang berbeda, pertimbangkan apakah skenario ini bisa dianggap sebagai penggunaan yang diperkirakan atau tidak atau benar-benar kebocoran memori. Misalnya, untuk berbagai fitur atau tugas pengguna, pertimbangkan kemungkinan berikut:
Kemungkinan besar terjadi kebocoran: Mengaktifkan skenario melalui beberapa iterasi akan mengakibatkan peningkatan penggunaan memori dari waktu ke waktu.
Kemungkinan besar terjadi penggunaan memori yang diperkirakan: Memori diklaim kembali setelah skenario dihentikan.
Kemungkinan terjadi penggunaan memori yang diperkirakan: Penggunaan memori meningkat selama jangka waktu tertentu kemudian menurun. Hal ini dapat disebabkan oleh cache yang dibatasi atau penggunaan memori lainnya yang diperkirakan.
Jika perilaku aplikasi menunjukkan kemungkinan besar terjadi penggunaan memori yang diperkirakan, masalah tersebut bisa diatasi dengan mengelola memori aplikasi Anda. Untuk mendapatkan bantuan, lihat Mengelola memori aplikasi.
Langkah 3: Lakukan debug di tingkat tinggi
Saat Anda men-debug kebocoran memori, mulailah di tingkat tinggi, lalu lihat perincian setelah Anda mempersempit kemungkinannya. Gunakan salah satu dari alat proses debug tingkat tinggi berikut untuk menganalisis terlebih dahulu apakah ada kebocoran dari waktu ke waktu:
Memory Profiler Android Studio (Direkomendasikan)
Memory Profiler Android Studio
Alat ini memberi Anda histogram visual tentang memori yang digunakan. Heap dump dan pelacakan alokasi juga dapat dipicu dari antarmuka yang sama ini. Alat ini adalah rekomendasi default. Untuk informasi selengkapnya, lihat Memory Profiler Android Studio.
Penghitung Memori Perfetto
Perfetto memberi Anda kontrol yang akurat terhadap pelacakan beberapa metrik dan menyajikan semuanya dalam satu histogram. Untuk informasi selengkapnya, lihat Penghitung Memori Perfetto.
Utilitas command line Android debug bridge (adb)
Sebagian besar data yang dapat dilacak dengan Perfetto juga tersedia sebagai utilitas command line adb
yang kuerinya dapat Anda kirim secara langsung. Dua contoh pentingnya adalah:
Meminfo memungkinkan Anda melihat informasi memori mendetail di waktu tertentu.
Procstats memberikan sejumlah statistik agregat yang penting dari waktu ke waktu.
Statistik penting yang harus dilihat di sini adalah jejak memori fisik maksimum (maxRSS) yang dibutuhkan aplikasi dari waktu ke waktu. MaxPSS mungkin tidak terlalu akurat. Cara untuk meningkatkan akurasi, lihat flag adb shell dumpsys procstats --help –start-testing
.
Pelacakan alokasi
Pelacakan alokasi mengidentifikasi stack trace tempat memori dialokasikan dan apakah memori belum dilepaskan. Langkah ini terutama berguna saat melacak kebocoran di kode native. Karena fungsinya untuk mengidentifikasi stack trace, alat ini sangat efektif untuk men-debug akar masalah dengan cepat atau mencari tahu cara membuat ulang masalah. Untuk langkah-langkah tentang cara menggunakan pelacakan alokasi, lihat Men-debug memori di kode native dengan pelacakan alokasi.
Langkah 4: Periksa penggunaan memori aplikasi dengan heap dump
Salah satu cara untuk mendeteksi kebocoran memori adalah mendapatkan heap dump aplikasi Anda dan kemudian memeriksanya apakah ada kebocoran. Heap dump adalah snapshot dari semua objek di memori aplikasi. Heap dump dapat digunakan untuk mendiagnosis kebocoran memori dan masalah lain yang terkait memori.
Android Studio dapat mendeteksi kebocoran memori yang tidak dapat diatasi oleh GC. Saat Anda merekam heap dump, Android Studio memeriksa apakah ada aktivitas atau fragmen yang masih dapat dijangkau tetapi sudah dihancurkan.
- Merekam heap dump.
- Menganalisis heap dump untuk menemukan kebocoran memori.
- Memperbaiki kebocoran memori.
Untuk mengetahui detailnya, lihat bagian berikut.
Merekam heap dump
Untuk merekam heap dump, Anda dapat menggunakan Android Debug Bridge (adb) atau Memory Profiler Android Studio.
Menggunakan adb untuk merekam heap dump
Untuk merekam heap dump menggunakan adb, ikuti langkah-langkah berikut:
- Hubungkan perangkat Android ke komputer.
- Buka command prompt dan arahkan ke direktori tempat alat adb berada.
Untuk merekam heap dump, jalankan perintah ini:
adb shell am dumpheap my.app.name $PHONE_FILE_OUT
Untuk mengambil heap dump, jalankan perintah ini:
adb pull $PHONE_FILE_OUT $LOCAL_FILE.
Menggunakan Android Studio untuk merekam heap dump
Untuk merekam heap dump menggunakan Memory Profiler Android Studio, ikuti langkah-langkah berikut di bagian Merekam heap dump Android.
Menganalisis heap dump untuk menemukan kebocoran memori
Setelah merekam heap dump, Anda dapat menggunakan Memory Profiler Android Studio untuk menganalisisnya. Untuk melakukannya, ikuti langkah-langkah ini:
Buka project Android Anda di Android Studio.
Pilih Run, lalu pilih konfigurasi Debug.
Buka tab Android Profiler.
Pilih Memory.
Pilih Open heap dump dan pilih file heap dump yang Anda buat. Memory profiler menampilkan grafik penggunaan memori aplikasi Anda.
Gunakan grafik untuk menganalisis heap dump:
Identifikasi objek yang tidak lagi digunakan.
Identifikasi objek yang menggunakan banyak memori.
Lihat berapa banyak memori yang digunakan setiap objek.
Gunakan informasi ini untuk mempersempit atau menemukan sumber kebocoran memori dan memperbaikinya.
Langkah 5: Perbaiki kebocoran memori
Setelah mengidentifikasi sumber kebocoran memori, Anda dapat memperbaikinya. Memperbaiki kebocoran memori di aplikasi Android akan membantu meningkatkan performa dan stabilitas aplikasi Anda. Bergantung pada skenario, detailnya bisa sangat bervariasi. Namun, saran berikut dapat membantu:
Pastikan aplikasi Anda mengalokasikan dan membatalkan alokasi memori seperti yang direkomendasikan oleh topik Android Mengelola memori aplikasi.
Hapus kode atau resource yang tidak digunakan dari aplikasi Anda. Untuk mengetahui detail terkait aplikasi Android, lihat Praktik terbaik untuk aplikasi Android.
Alat proses debug lainnya
Setelah langkah-langkah ini diselesaikan, jika Anda masih belum menemukan dan memperbaiki kebocoran memori, cobalah alat berikut:
- Men-debug memori di kode native dengan pelacakan alokasi.
- Mengidentifikasi kebocoran dengan LeakCanary.
Men-debug memori di kode native dengan pelacakan alokasi
Meskipun Anda tidak langsung menggunakan kode native, beberapa library Android umum menggunakannya, termasuk SDK Google. Jika Anda merasa kebocoran memori terjadi di kode native, ada beberapa alat yang dapat Anda gunakan untuk men-debugnya. Pelacakan alokasi dengan Android Studio atau heapprofd (juga kompatibel dengan Perfetto) adalah cara ideal untuk mengidentifikasi kemungkinan penyebab kebocoran memori dan sering kali menjadi cara tercepat untuk men-debug.
Pelacakan alokasi juga memiliki keunggulan unik yaitu mengizinkan Anda untuk membagikan hasil tanpa menyertakan informasi sensitif yang dapat ditemukan di heap.
Mengidentifikasi kebocoran dengan LeakCanary
LeakCanary adalah alat canggih untuk mengidentifikasi kebocoran memori di aplikasi Android. Untuk mempelajari lebih lanjut cara menggunakan LeakCanary di aplikasi Anda, kunjungi LeakCanary.
Cara melaporkan masalah terkait SDK Google
Jika Anda telah mencoba semua metode dalam dokumen ini dan menduga ada kebocoran memori di SDK kami, hubungi dukungan pelanggan dengan memberikan sebanyak mungkin informasi berikut:
Langkah-langkah untuk membuat ulang kebocoran memori. Jika langkah-langkah tersebut memerlukan coding yang kompleks, menyalin kode yang mereplikasi masalah ke aplikasi contoh dan memberikan langkah tambahan yang perlu diambil di UI untuk memicu kebocoran mungkin akan membantu.
Heap dump yang direkam dari aplikasi Anda dengan masalah yang dibuat ulang. Rekam heap dump di dua titik yang berbeda saat terindikasi penggunaan memori meningkat secara signifikan.
Jika kebocoran memori native diperkirakan terjadi, bagikan output pelacakan alokasi dari heapprofd.
Laporan bug diambil setelah Anda membuat ulang kondisi kebocoran.
Stack trace untuk error terkait memori.
Catatan penting: Stack trace itu sendiri biasanya tidak memadai untuk men-debug masalah memori, jadi pastikan Anda juga memberikan salah satu bentuk informasi lainnya.