Sebelumnya, Android hanya mendukung ukuran halaman memori 4 KB, yang telah mengoptimalkan performa memori sistem untuk jumlah total memori rata-rata yang biasanya dimiliki perangkat Android. Mulai dari Android 15, AOSP mendukung perangkat yang dikonfigurasi untuk menggunakan ukuran halaman 16 KB (perangkat 16 KB). Jika aplikasi Anda menggunakan library NDK, baik secara langsung maupun tidak langsung melalui SDK, Anda harus membangun ulang aplikasi agar dapat berfungsi di perangkat 16 KB ini.
Seiring produsen perangkat terus membuat perangkat dengan jumlah memori fisik (RAM) yang lebih besar, banyak perangkat ini akan mengadopsi ukuran halaman 16 KB (dan pada akhirnya lebih besar) untuk mengoptimalkan performa perangkat. Menambahkan dukungan untuk perangkat dengan ukuran halaman 16 KB memungkinkan aplikasi Anda berjalan di perangkat ini dan membantu aplikasi Anda mendapatkan manfaat dari peningkatan performa terkait. Tanpa dikompilasi ulang, aplikasi tidak akan berfungsi di perangkat 16 KB dalam rilis Android mendatang.
Untuk membantu Anda menambahkan dukungan bagi aplikasi, kami telah memberikan panduan tentang cara memeriksa apakah aplikasi Anda terpengaruh, cara membangun ulang aplikasi (jika berlaku), dan cara menguji aplikasi Anda di lingkungan 16 KB menggunakan emulator (termasuk image sistem Android 15 untuk Android Emulator).
Persyaratan kompatibilitas Google Play
Untuk memastikan aplikasi Anda berfungsi dengan benar di versi Android terbaru, semua aplikasi yang menargetkan Android 15 (level API 35) dan yang lebih tinggi harus mendukung ukuran halaman memori 16 KB di perangkat 64-bit di Google Play. Mulai 1 Februari 2027, jika update aplikasi Anda tidak mendukung ukuran halaman memori 16 KB, Anda tidak akan dapat merilis update tersebut.
Manfaat dan peningkatan performa
Perangkat yang dikonfigurasi dengan ukuran halaman 16 KB menggunakan memori yang sedikit lebih banyak secara rata-rata, tetapi juga mendapatkan berbagai peningkatan performa untuk sistem dan aplikasi:
- Waktu peluncuran aplikasi lebih rendah saat sistem berada dalam tekanan memori: rata-rata 3,16% lebih rendah, dengan peningkatan yang lebih signifikan (hingga 30%) untuk beberapa aplikasi yang kami uji
- Mengurangi penggunaan daya selama peluncuran aplikasi: Pengurangan rata-rata 4,56%
- Peluncuran kamera lebih cepat: rata-rata hot start 4,48% lebih cepat dan cold start 6,60% lebih cepat
- Waktu booting sistem yang lebih baik: rata-rata meningkat sebesar 8% (sekitar 950 milidetik)
Peningkatan ini didasarkan pada pengujian awal kami, dan hasil pada perangkat aktual kemungkinan akan berbeda. Kami akan memberikan analisis tambahan tentang potensi keuntungan untuk aplikasi saat kami melanjutkan pengujian.
Memeriksa apakah aplikasi Anda terpengaruh
Jika aplikasi Anda menggunakan kode native, Anda harus membangun ulang aplikasi dengan dukungan untuk perangkat 16 KB. Jika tidak yakin apakah aplikasi Anda menggunakan kode native atau tidak, Anda dapat menggunakan APK Analyzer untuk mengidentifikasi apakah ada kode native atau tidak, lalu memeriksa perataan segmen ELF untuk library bersama yang Anda temukan. Android Studio juga menyediakan fitur yang membantu Anda mendeteksi masalah perataan secara otomatis.
Jika aplikasi Anda hanya menggunakan kode yang ditulis dalam bahasa pemrograman Java atau di Kotlin, termasuk semua library atau SDK, berarti aplikasi Anda sudah mendukung perangkat 16 KB. Namun, sebaiknya Anda menguji aplikasi di lingkungan 16 KB untuk memverifikasi bahwa tidak ada regresi perilaku aplikasi yang tidak terduga.
Apakah aplikasi Anda menggunakan kode native?
Aplikasi Anda menggunakan kode native jika salah satu hal berikut berlaku:
- Aplikasi Anda menggunakan kode C/C++ (native). Jika aplikasi Anda menggunakan Android NDK, berarti aplikasi Anda menggunakan kode native.
- Aplikasi Anda terhubung dengan library atau dependensi native pihak ketiga (seperti SDK) yang menggunakannya.
- Aplikasi Anda dibuat oleh pembuat aplikasi pihak ketiga yang menggunakan library native di perangkat.
Mengidentifikasi library native menggunakan APK Analyzer
APK Analyzer adalah alat yang memungkinkan Anda mengevaluasi berbagai aspek APK yang telah dibangun. Untuk memeriksa apakah aplikasi Anda menggunakan kode native (terlepas dari apakah aplikasi tersebut kompatibel dengan 16 KB):
- Buka Android Studio, lalu klik File > Open dan pilih project apa saja.
Dari panel menu, klik Build > Analyze APK...
Pilih APK yang ingin Anda analisis.
Lihat di dalam folder
lib, yang menghosting file objek bersama (.so) jika ada. Jika ada file objek bersama, aplikasi Anda menggunakan kode native. Kolom Alignment menampilkan pesan peringatan untuk file yang memiliki masalah penyelarasan. Jika tidak ada file objek bersama atau tidak ada folderlib, berarti aplikasi Anda tidak menggunakan kode native.
Mendeteksi masalah penyelarasan dengan pemeriksaan otomatis
Android Studio akan memberikan peringatan secara proaktif jika library atau APK bawaan Anda tidak mematuhi ukuran halaman 16 KB. Gunakan alat APK Analyzer untuk meninjau library mana yang perlu diupdate atau apakah ada perubahan kode yang diperlukan.
Lint di Android Studio juga menandai library native yang tidak selaras dengan 16 KB.
Memeriksa keselarasan segmen ELF untuk pustaka bersama
Untuk library bersama, pastikan segmen ELF library bersama diselaraskan dengan benar menggunakan penyelarasan ELF 16 KB.
Menggunakan APK Analyzer (Direkomendasikan)
Cara termudah untuk memverifikasi perataan pustaka bersama adalah dengan menggunakan APK Analyzer di Android Studio. Jika file objek bersama tidak selaras dengan 16 KB, kolom Alignment akan menampilkan pesan peringatan.
Menggunakan skrip check_elf_alignment.sh (Linux atau macOS)
Jika Anda mengembangkan aplikasi di Linux atau macOS dan lebih suka menggunakan skrip, Anda
dapat menggunakan skrip check_elf_alignment.sh:
Simpan skrip
check_elf_alignment.shke file.Jalankan skrip pada file APK aplikasi Anda:
check_elf_alignment.sh APK_NAME.apkSkrip akan menghasilkan
ALIGNEDatauUNALIGNEDuntuk semua pustaka bersamaarm64-v8a.Jika ada library bersama
arm64-v8aataux86_64yangUNALIGNED, Anda harus memperbarui pengemasan untuk library tersebut, lalu mengompilasi ulang aplikasi dan menguji ulang dengan mengikuti langkah-langkah di bagian ini.
Menggunakan alat command line secara langsung
Ikuti langkah-langkah berikut untuk memeriksa penyelarasan segmen ELF menggunakan alat command line secara langsung:
- Pastikan Android SDK Build-Tools versi 35.0.0 atau yang lebih tinggi dan
Android NDK diinstal menggunakan SDK Manager di Android Studio atau
alat command line
sdkmanager. Ekstrak file APK aplikasi Anda:
Linux atau macOS
unzip APK_NAME.apk -d /tmp/my_apk_outWindows (PowerShell)
Expand-Archive -Path .\APK_NAME.apk -DestinationPath ~\tmp\my_apk_outDi direktori sementara tempat Anda mengekstrak file APK, periksa konten direktori
libuntuk file objek bersama (.so). File ini adalah file objek bersama yang sama dengan yang Anda lihat saat mengidentifikasi library native menggunakan APK Analyzer. Jalankan perintah berikut pada setiap file objek bersama:Linux atau macOS
SDK_ROOT_LOCATION/Android/sdk/ndk/NDK_VERSION/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-objdump -p SHARED_OBJECT_FILE.so | grep LOADWindows (PowerShell)
SDK_ROOT_LOCATION\Android\sdk\ndk\NDK_VERSION\toolchains\llvm\prebuilt\windows-x86_64\bin\llvm-objdump.exe -p SHARED_OBJECT_FILE.so | Select-String -Pattern "LOAD"Dengan
SDK_ROOT_LOCATIONadalah jalur ke direktori tempat Anda menginstal Android SDK,SHARED_OBJECT_FILEadalah nama file objek bersama yang Anda periksa, danNDK_VERSIONadalah versi Android NDK yang telah Anda instal (misalnya,28.0.12433566). Outputnya akan terlihat seperti berikut untuk setiap file yang Anda periksa:LOAD off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**14 LOAD off 0x0000000000042a90 vaddr 0x0000000000043a90 paddr 0x0000000000043a90 align 2**14 LOAD off 0x0000000000046230 vaddr 0x0000000000048230 paddr 0x0000000000048230 align 2**14Periksa baris output untuk memastikan bahwa segmen beban tidak memiliki nilai kurang dari
2**14. Jika ada segmen pemuatan yang bernilai2**13,2**12, atau lebih rendah, Anda harus mengupdate paket untuk library tersebut, lalu mengompilasi ulang aplikasi dan menguji ulang dengan mengikuti langkah-langkah di bagian ini.Selanjutnya, jalankan alat command line
zipalignpada file APK aplikasi Anda:Linux atau macOS
SDK_ROOT_LOCATION/Android/sdk/build-tools/35.0.0/zipalign -v -c -P 16 4 APK_NAME.apkWindows (PowerShell)
SDK_ROOT_LOCATION\Android\sdk\build-tools\35.0.0\zipalign.exe -v -c -P 16 4 APK_NAME.apkDengan
SDK_ROOT_LOCATIONadalah jalur ke direktori tempat Anda menginstal Android SDK, danAPK_NAMEadalah nama file APK aplikasi Anda. Baris terakhir output akan menampilkan "Verification successful" jika semua pustaka bersama disejajarkan dengan benar.Jika verifikasi gagal, beberapa library bersama perlu disesuaikan, jadi Anda harus mengupdate paket untuk library tersebut, lalu mengompilasi ulang aplikasi dan menguji ulang dengan mengikuti langkah-langkah di bagian ini.
Memeriksa tanda keamanan RELRO
Untuk mengurangi eksploitasi keamanan, penaut modern menggunakan
flag Relocation Read-Only (RELRO) untuk membuat bagian target relokasi (seperti .got dan .data.rel.ro) dari file objek bersama
menjadi hanya baca setelah relokasi dinamis selesai.
Aktifkan flag RELRO di build Anda.
Jika GNU_RELRO berbagi segmen LOAD yang dapat ditulis dengan data berikutnya yang dapat ditulis
(seperti .data atau .bss), alamat akhir segmen GNU_RELRO
(VirtAddr + MemSiz) harus selaras dengan 16 KB (0x4000). Jika tidak, saat
Android Linker menandai halaman 16 KB yang berisi akhir
GNU_RELRO sebagai hanya baca, data yang dapat ditulis yang berdekatan dan berada di sisa
halaman 16 KB yang sama juga akan menjadi hanya baca, sehingga menyebabkan aplikasi error saat
runtime dengan kesalahan segmentasi (SIGSEGV) saat data tersebut ditulis.
Hal ini biasanya terjadi jika file .so dibuat dengan toolchain NDK r27 dan
yang lebih rendah tanpa mengaktifkan flag yang relevan.
Menggunakan APK Analyzer (Direkomendasikan)
Anda dapat menggunakan APK Analyzer di Android Studio untuk memeriksa status perataan RELRO file objek bersama secara langsung.
Menggunakan alat command line
Jika Anda lebih suka memeriksa penyelarasan secara manual atau perlu mengotomatiskan prosesnya, ikuti langkah-langkah berikut:
Langkah 1: Periksa header program
Jalankan perintah berikut pada setiap file objek bersama (di Linux, ganti
darwin-x86_64 dengan linux-x86_64):
Linux atau macOS
SDK_ROOT_LOCATION/Android/sdk/ndk/NDK_VERSION/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-readelf -Wl SHARED_OBJECT_FILE.so | grep 'LOAD\|RELRO\|Type'
Windows (PowerShell)
SDK_ROOT_LOCATION\Android\sdk\ndk\NDK_VERSION\toolchains\llvm\prebuilt\windows-x86_64\bin\llvm-readelf.exe -Wl SHARED_OBJECT_FILE.so | Select-String -Pattern 'LOAD|RELRO|Type'
String GNU_RELRO dicetak jika ada segmen RELRO.
Langkah 2: Verifikasi kepatuhan 16 KB untuk RELRO
File objek bersama mematuhi ukuran halaman 16 KB sehubungan dengan RELRO jika salah satu kondisi berikut terpenuhi:
- Tidak ada segmen
GNU_RELROdi header program. - Alamat akhir
GNU_RELROdiselaraskan dengan 16 KB: Jumlah alamat virtualnya (VirtAddr) dan ukuran memori (MemSiz) dibagi 16 KB (0x4000) menyisakan sisa (modulo) nol:(VirtAddr + MemSiz) % 0x4000 == 0. - Tidak ada data yang dapat ditulis setelah
GNU_RELROdi segmenLOADyang sama:GNU_RELROmenempati seluruh sisa segmenLOADyang memuatnya (artinyaLOAD.VirtAddr + LOAD.MemSiz == RELRO.VirtAddr + RELRO.MemSiz), sehingga tidak ada bagian.dataatau.bssyang dapat ditulis yang berbagi halaman akhir.
Contoh
Contoh berikut menunjukkan cara mengevaluasi output llvm-readelf untuk berbagai konfigurasi GNU_RELRO.
Contoh 1: File .so yang tidak selaras (Tidak mematuhi kebijakan)
Dalam contoh ini, GNU_RELRO berbagi segmen RW LOAD dengan data berikutnya yang dapat ditulis, dan alamat akhirnya bukan kelipatan 0x4000:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x0cfaf0 0x0cfaf0 R E 0x4000
LOAD 0x0cfaf0 0x00000000000dfaf0 0x00000000000dfaf0 0x02510 0x04510 RW 0x4000
GNU_RELRO 0x0cfaf0 0x00000000000dfaf0 0x00000000000dfaf0 0x01510 0x01510 R 0x1
- Formula:
(VirtAddr + MemSiz) % 0x4000 == 0 - Hasil:
(0xdfaf0 + 0x01510) % 0x4000 = 0xE1000 % 0x4000 == 0x1000
Karena 0x1000 bukan nol, dan segmen LOAD yang memuatnya berlanjut melewati
0xE1000 (berakhir di 0xdfaf0 + 0x04510 = 0xE4000), file .so ini tidak
mematuhi 16 KB. Pada perangkat 16 KB, penaut membulatkan rentang perlindungan RELRO ke batas halaman 16 KB, sehingga menandai 0xDC000 (batas halaman sebelumnya) hingga 0xE4000 sebagai hanya baca. Namun, bagian .data dan .bss yang dapat ditulis dari file .so berada dalam subrentang dari 0xE1000 hingga 0xE4000, sehingga menghasilkan kesalahan segmentasi saat diubah pada runtime. Bangun ulang file .so
ini seperti yang dijelaskan di bagian
Kompilasi aplikasi Anda menggunakan penyelarasan ELF 16 KB.
Contoh 2: File .so yang selaras dengan segmen RELRO (Sesuai)
Dalam contoh ini, akhir segmen GNU_RELRO berada di batas halaman 16 KB:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x0cfaf0 0x0cfaf0 R E 0x4000
LOAD 0x0cfaf0 0x00000000000dfaf0 0x00000000000dfaf0 0x01510 0x03510 RW 0x4000
GNU_RELRO 0x0cfaf0 0x00000000000dfaf0 0x00000000000dfaf0 0x00510 0x00510 R 0x1
- Formula:
(VirtAddr + MemSiz) % 0x4000 == 0 - Hasil:
(0xdfaf0 + 0x00510) % 0x4000 = 0xE0000 % 0x4000 == 0
Karena sisanya adalah 0, perlindungan RELRO berakhir dengan baik di batas halaman 0xE0000, sehingga data yang dapat ditulis mulai dari 0xE0000 tidak terpengaruh.
Contoh 3: File .so tanpa segmen RELRO (Sesuai)
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x000680 0x000680 R E 0x4000
LOAD 0x000680 0x0000000000004680 0x0000000000004680 0x0001d8 0x0001d8 RW 0x4000
File .so ini tidak memiliki segmen GNU_RELRO, sehingga masalah batas halaman RELRO tidak berlaku (meskipun mengaktifkan RELRO tetap direkomendasikan untuk keamanan).
Contoh 4: GNU_RELRO di segmen LOAD-nya sendiri (Sesuai)
Dalam contoh ini, GNU_RELRO tidak berakhir pada batas 16 KB, tetapi masih mematuhi karena tidak ada data yang dapat ditulis yang mengikutinya di segmen LOAD yang sama:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x000680 0x000680 R E 0x4000
LOAD 0x000680 0x0000000000004680 0x0000000000004680 0x0001d8 0x000980 RW 0x4000
GNU_RELRO 0x000680 0x0000000000004680 0x0000000000004680 0x0001d8 0x000980 R 0x1
- Formula:
(VirtAddr + MemSiz) % 0x4000 == 0 - Hasil:
(0x4680 + 0x0980) % 0x4000 = 0x5000 % 0x4000 == 0x1000
Meskipun 0x1000 bukan nol, file .so ini masih mematuhi ukuran halaman 16 KB.
Membandingkan GNU_RELRO dengan segmen LOAD yang memuatnya (entri LOAD
kedua) menunjukkan bahwa keduanya dimulai pada VirtAddr 0x4680 dan berakhir pada alamat yang sama persis (0x4680 + 0x0980 = 0x5000).
Karena seluruh segmen LOAD hanya berisi data RELRO, tidak ada
data .data atau .bss yang dapat ditulis dalam subrentang dari 0x5000 hingga 0x8000
(library tidak memiliki data yang dapat ditulis non-RELRO, atau segmen LOAD
yang dapat ditulis berikutnya dimulai pada batas halaman 16 KB terpisah di 0x8000 atau
lebih). Perlindungan hanya baca penaut tidak akan tumpang-tindih dengan data yang dapat ditulis,
sehingga tidak terjadi kesalahan segmentasi.
Membangun aplikasi dengan dukungan untuk perangkat 16 KB
Jika aplikasi Anda menggunakan kode native, selesaikan langkah-langkah yang diuraikan di bagian berikut untuk memastikan aplikasi Anda mendukung perangkat 16 KB:
- Update pengemasan pustaka bersama Anda
- Mengompilasi aplikasi menggunakan penyelarasan ELF 16 KB
- Memperbaiki kode dan menyelesaikan masalah runtime
- Mengoptimalkan pengalokasi memori kustom (jika ada)
- Memeriksa dukungan 16 KB pada SDK
Mengupdate paket pustaka bersama
Upgrade ke AGP versi 8.5.1 atau yang lebih tinggi dan gunakan pustaka bersama yang tidak dikompresi.
Menggunakan bundletool untuk memverifikasi zip alignment
Untuk melihat penyelarasan paket, gunakan:
bundletool dump config --bundle=<my .aab> | grep alignment
Jika Anda melihat PAGE_ALIGNMENT_16K, berarti Anda tahu bahwa paket Anda meminta perataan zip 16 KB. Jika Anda melihat PAGE_ALIGNMENT_4K, ini menginstruksikan APK yang di-build dari
AAB ini untuk memiliki file .so yang selaras 4 KB dalam file zip.
AGP versi 8.5.1 atau yang lebih tinggi
Perangkat 16 KB memerlukan aplikasi yang dikirim dengan pustaka bersama yang tidak dikompresi untuk menyelaraskannya pada batas zip-aligned 16 KB. Untuk melakukannya, Anda harus mengupgrade ke Plugin Android Gradle (AGP) versi 8.5.1 atau yang lebih tinggi. Lihat bagian Asisten Upgrade plugin Android Gradle untuk mengetahui detail tentang proses upgrade.
AGP versi 8.5 atau yang lebih rendah
Jika Anda tidak dapat mengupgrade AGP ke versi 8.5.1 atau yang lebih tinggi, alternatifnya adalah beralih menggunakan pustaka bersama yang dikompresi. Update konfigurasi Gradle Anda agar Gradle mengompresi library bersama saat memaketkan aplikasi untuk menghindari masalah penginstalan aplikasi dengan library bersama yang tidak selaras.
Groovy
Di file build.gradle, tambahkan opsi berikut:
android {
...
packagingOptions {
jniLibs {
useLegacyPackaging true
}
}
}
Kotlin
Di file build.gradle.kts, tambahkan opsi berikut:
android {
...
packagingOptions {
jniLibs {
useLegacyPackaging = true
}
}
}
AGP versi 8.0 atau yang lebih rendah
Jika Anda menggunakan versi AGP yang sama atau lebih rendah dari 8.0, Anda juga harus menonaktifkan
opsi library native yang tidak dikompresi untuk App Bundle di
file gradle.properties:
android.bundle.enableUncompressedNativeLibs=false
Mengompilasi aplikasi Anda menggunakan penyelarasan ELF 16 KB
Perangkat 16 KB memerlukan segmen ELF library bersama untuk diselaraskan dengan benar menggunakan penyelarasan ELF 16 KB agar aplikasi Anda dapat berjalan.
Untuk developer game, jika game Anda berjalan di atas game engine Unity, lihat panduan Unity. Jika game Anda berjalan di atas game engine Unreal, lihat panduan Unreal.Untuk game engine native, lanjutkan dengan panduan ini.
Untuk mengompilasi aplikasi menggunakan perataan ELF 16 KB, selesaikan langkah-langkah di salah satu bagian berikut, bergantung pada versi Android NDK yang Anda gunakan.
Android NDK r28 dan yang lebih tinggi
NDK versi r28 dan yang lebih tinggi mengompilasi perataan 16 KB secara default.
Android NDK r27 dan yang lebih lama
Untuk mendukung kompilasi pustaka bersama yang selaras dengan 16 KB menggunakan Android NDK versi r27 atau yang lebih rendah, gunakan flag penaut berikut:
-Wl,-z,max-page-size=16384
-Wl,-z,common-page-size=16384
Berikut cara mengupdate file konfigurasi sistem build Anda:
ndk-build
Jika Anda menggunakan ndk-build, update Android.mk untuk mengaktifkan perataan ELF
16 KB:
LOCAL_LDFLAGS += -Wl,-z,max-page-size=16384 -Wl,-z,common-page-size=16384
CMake
Jika Anda menggunakan CMake, update CMakeLists.txt untuk mengaktifkan perataan ELF 16 KB:
target_link_options(${CMAKE_PROJECT_NAME} PRIVATE
"-Wl,-z,max-page-size=16384"
"-Wl,-z,common-page-size=16384"
)
Memperbaiki kode dan menyelesaikan masalah runtime
Meskipun diselaraskan dengan 16 KB, aplikasi Anda dapat mengalami error jika ada bagian dalam kode Anda yang mengasumsikan bahwa perangkat menggunakan ukuran halaman tertentu. Untuk menghindari hal ini, selesaikan langkah-langkah berikut:
Hapus dependensi hard code yang mereferensikan konstanta atau instance
PAGE_SIZEdalam logika kode Anda yang mengasumsikan bahwa ukuran halaman perangkat adalah 4 KB (4096).Sebagai gantinya, gunakan
getpagesize()atausysconf(_SC_PAGESIZE).Cari penggunaan
mmap()dan API lain yang memerlukan argumen yang selaras dengan halaman, lalu ganti dengan alternatif jika diperlukan.
Dalam beberapa kasus, jika aplikasi Anda menggunakan PAGE_SIZE sebagai nilai praktis yang tidak
terikat dengan ukuran halaman yang mendasarinya, hal ini tidak akan menyebabkan aplikasi Anda rusak saat
digunakan dalam mode 16 KB. Namun, jika nilai ini diteruskan ke kernel dengan
mmap tanpa MAP_FIXED, kernel masih menggunakan seluruh halaman, yang akan memboroskan
beberapa memori. Oleh karena itu, PAGE_SIZE tidak ditentukan saat mode 16 KB
diaktifkan di NDK r27 dan yang lebih tinggi.
Jika aplikasi Anda menggunakan PAGE_SIZE dengan cara ini dan tidak pernah meneruskan nilai ini secara langsung ke
kernel, maka alih-alih menggunakan PAGE_SIZE, buat variabel baru dengan nama
baru untuk mencerminkan bahwa variabel tersebut digunakan untuk tujuan lain dan tidak mencerminkan halaman memori
yang sebenarnya.
Mengoptimalkan pengalokasi memori kustom
Pada sistem 16 KB, unit memori fisik terkecil yang dialokasikan sistem operasi berukuran empat kali lebih besar daripada sistem 4 KB. Jika pengalokasi kustom didesain berdasarkan asumsi 4 KB, pengalokasi tersebut dapat menyebarkan objek kecil di beberapa halaman 16 KB dan mempertahankan memori kosong yang tidak perlu. Hal ini dapat meningkatkan penggunaan memori fisik (RSS) secara signifikan dan menurunkan efisiensi swap terkompresi (ZRAM).
Jika kode Anda mengelola kumpulan memorinya sendiri, ikuti rekomendasi berikut:
1. Menghindari nilai minimum byte hard code untuk mengosongkan memori
Banyak pengalokasi menggunakan batas byte tetap untuk memutuskan kapan harus merilis memori kembali ke
OS menggunakan madvise(MADV_DONTNEED) (misalnya, hanya merilis memori jika
objek aktif menggunakan kurang dari 8 KB).
Pada sistem 16 KB, bahkan satu objek aktif 16 byte menyematkan seluruh halaman 16 KB (yang lebih besar dari 8 KB). Akibatnya, nilai minimum rilis tidak pernah terpenuhi, dan pengalokasi tidak pernah mengembalikan memori di sekitarnya yang tidak digunakan ke kernel.
Yang harus dilakukan: Jangan pernah menggunakan konstanta byte hard code untuk heuristik rilis halaman.
Skalakan nilai minimum rilis secara dinamis saat runtime berdasarkan ukuran halaman sebenarnya
menggunakan sysconf(_SC_PAGESIZE).
2. Mengisi halaman yang sudah digunakan terlebih dahulu (alokasi dense-first)
Jika pengalokasi membagikan memori dalam urutan first-in-first-out (FIFO) atau round-robin, alokasi baru akan tersebar di banyak halaman 16 KB yang terisi sebagian. Satu objek di halaman membuat semua 16 KB tetap berada di RAM fisik.
Yang harus dilakukan: Selalu alokasikan objek baru dari halaman atau slab yang paling penuh (paling padat) sebelum menyentuh halaman yang kosong atau jarang digunakan. Memusatkan alokasi baru pada halaman yang sudah kotor memungkinkan halaman yang jarang digunakan secara alami terkuras hingga nol objek aktif, sehingga seluruh halaman 16 KB dapat dirilis ke OS.
3. Menyelaraskan kumpulan memori ke 16 KB dan menjaga ukuran kumpulan tetap sedang
Rentang multi-halaman yang dirancang untuk sistem 4 KB dapat menampung kelonggaran memori yang belum dirilis secara berlebihan pada kernel 16 KB. Selain itu, class ukuran yang tidak dibagi secara merata menjadi 16 KB akan menyebabkan fragmentasi di akhir setiap halaman.
Yang harus dilakukan:
- Pastikan semua kumpulan memori, batas slab, dan perataan buffer adalah kelipatan persis dari ukuran halaman runtime.
- Evaluasi ulang ukuran span multi-halaman untuk class objek kecil guna menghindari alokasi slab yang terlalu besar yang menjebak memori tidak ada aktivitas.
4. Segera lepaskan memori fisik untuk buffer besar yang di-cache
Alokator kustom sering kali meng-cache buffer besar (> 64 KB) dalam kumpulan dalam memori
sehingga dapat digunakan kembali tanpa membayar overhead panggilan sistem
mmap atau munmap. Namun, mempertahankan buffer kotor ini dalam memori akan membuang megabyte
RAM fisik saat menunggu timer pengeluaran.
Yang harus dilakukan: Tetap sediakan rentang alamat memori virtual untuk digunakan kembali dengan cepat,
tetapi segera panggil madvise(..., MADV_DONTNEED) atau madvise(..., MADV_FREE)
saat mengembalikan buffer ke cache. Sistem operasi akan segera mengklaim kembali RAM fisik, sementara aplikasi Anda masih dapat menggunakan kembali alamat virtual secara instan tanpa mengalokasikan ulang.
5. Mengosongkan memori saat bebas, bukan saat alokasi untuk kompresi ZRAM
Android menggunakan swap terkompresi (ZRAM) untuk menyimpan aplikasi latar belakang dalam memori. Di perangkat 16 KB, jika halaman menyimpan satu objek aktif, seluruh halaman 16 KB akan tetap berada di RAM atau ditukar ke ZRAM. Data sampah yang tersisa (seperti pointer dan string yang tidak berlaku) pada bagian halaman yang sebelumnya dikosongkan tidak dapat dikompresi dengan baik.
Jika pengalokasi Anda melakukan inisialisasi nol pada memori (seperti untuk keamanan atau alokasi yang diinisialisasi nol), pertimbangkan untuk melakukan inisialisasi nol saat dealokasi (free()), bukan saat alokasi:
- Halaman yang disematkan lebih hemat biaya: Memori tidak ada aktivitas di halaman 16 KB yang terisi sebagian akan dikompresi hingga hampir tidak ada di ZRAM, sehingga halaman yang disematkan tidak membuang-buang ruang swap fisik.
- Overhead cache minimal: Pada saat
free()dipanggil, memori sudah panas di cache CPU, sehingga menghindari cache tidak ditemukan tambahan di kemudian hari.
Ringkasan rekomendasi
| Area | Rekomendasi | Dampak yang diharapkan |
|---|---|---|
| Nilai minimum penghapusan permanen | Skalakan nilai minimum rilis secara dinamis menggunakan sysconf(_SC_PAGESIZE). |
Mencegah logika rilis mengalami deadlock permanen. |
| Urutan alokasi | Alokasikan dari halaman atau slab yang paling padat (hampir penuh) terlebih dahulu. | Mengurangi memori residen (RSS) dengan mengemas objek aktif bersama-sama. |
| Ukuran span | Sejajarkan class ukuran dengan kelipatan 16 KB dan hindari slab yang terlalu besar. | Menghilangkan fragmentasi halaman akhir dan mengurangi kelonggaran memori. |
| Cache buffer | Panggil madvise(MADV_DONTNEED) segera saat meng-cache buffer besar. |
Menghilangkan bloat RAM yang tidak ada aktivitasnya sekaligus mempertahankan penggunaan kembali virtual yang cepat. |
| Swap / ZRAM | Mengosongkan memori pada free(), bukan pada alokasi. |
Meningkatkan rasio kompresi ZRAM sehingga halaman yang disematkan memerlukan biaya lebih sedikit. |
Memeriksa dukungan 16 KB pada SDK
Banyak SDK yang kompatibel dengan ukuran halaman 16 KB, terutama jika Anda mem-build-nya sendiri atau mendapatkan versi bawaan terbaru. Namun, karena beberapa SDK bawaan atau versi SDK tidak kompatibel dengan 16 KB, Anda harus memeriksa situs setiap penyedia SDK untuk menentukan versi yang akan digunakan dengan 16 KB.
Menguji aplikasi Anda di lingkungan 16 KB
Setelah mem-build aplikasi dengan dukungan untuk perangkat 16 KB, Anda perlu menguji aplikasi di lingkungan 16 KB untuk melihat apakah aplikasi mengalami regresi. Untuk melakukannya, ikuti langkah-langkah ini:
Siapkan Android 15 SDK atau yang lebih baru.
Siapkan salah satu lingkungan pengujian berikut:
- Menyiapkan Android Emulator dengan image sistem Android 15 berbasis 16 KB
- Menggunakan Cuttlefish dengan ukuran halaman 16 KB di ARM64
- Menyimulasikan Cuttlefish dengan ukuran halaman 16 KB di x86-64
- Mengaktifkan mode 16 KB di perangkat menggunakan opsi developer
- Gunakan Samsung Remote Test Lab di perangkat yang didukung 16 KB
Mulai perangkat pengujian, lalu jalankan perintah berikut untuk memverifikasi bahwa perangkat menggunakan lingkungan 16 KB:
adb shell getconf PAGE_SIZEPerintah akan menampilkan nilai
16384.Jalankan perintah
zipalignberikut untuk memverifikasi bahwa aplikasi Anda disejajarkan dengan 16 KB, dengan APK_NAME adalah nama file APK aplikasi Anda:zipalign -c -P 16 -v 4 APK_NAME.apkUji aplikasi Anda secara menyeluruh, dengan berfokus pada area yang mungkin terpengaruh oleh perubahan instance kode yang mereferensikan ukuran halaman tertentu.
Menyiapkan Android Emulator dengan image sistem berbasis 16 KB
Untuk menyiapkan lingkungan 16 KB menggunakan Android Emulator, ikuti langkah-langkah berikut:
- Di Android Studio, klik Tools > SDK Manager.
Di tab SDK Platforms, pilih Show Package Details, lalu luaskan bagian Android VanillaIceCream atau yang lebih tinggi dan pilih salah satu atau kedua image sistem emulator berikut, bergantung pada perangkat virtual yang ingin Anda buat:
- Image Sistem ARM 64 v8a Ukuran Halaman 16 KB Eksperimental Google API
- Image Sistem Atom Intel x86_64 Ukuran Halaman 16 KB Eksperimental Google API
Klik Apply > OK untuk mendownload image sistem yang Anda pilih.
Ikuti langkah-langkah untuk menyiapkan perangkat virtual untuk Android 15, dan saat diminta untuk memilih image sistem, pilih image sistem 16 KB yang Anda download. Jika tidak direkomendasikan secara otomatis, Anda dapat menemukan image sistem 16 KB di tab Other Images.
Meluncurkan emulator
Setelah Anda selesai menyiapkan Android Emulator dan perangkat virtual, luncurkan emulator dari menu perangkat target, atau dari command line.
Mengaktifkan mode 16 KB di perangkat menggunakan opsi developer
Aktifkan opsi developer Boot dengan ukuran halaman 16 KB untuk mem-boot perangkat dalam mode 16 KB.
Dalam versi QPR Android 15, Anda dapat menggunakan opsi developer yang tersedia di perangkat tertentu untuk mem-boot perangkat dalam mode 16 KB dan melakukan pengujian di perangkat. Sebelum menggunakan opsi developer, buka Setelan > Sistem > Update software dan terapkan update yang tersedia.
Opsi developer ini tersedia di perangkat berikut:
Pixel 8 dan 8 Pro (dengan Android 15 QPR1 atau yang lebih tinggi)
Pixel 8a (dengan Android 15 QPR1 atau yang lebih baru)
Pixel 9, 9 Pro, dan 9 Pro XL (dengan Android 15 QPR2 atau yang lebih baru)
Pixel 9a (dengan Android 16 atau yang lebih baru)
Mode kompatibilitas mundur 16 KB
Peringatan dalam mode kompatibilitas ukuran halaman
Opsi kompatibilitas mundur 16 KB tersedia saat perangkat berjalan dengan kernel 16 KB. Pengelola paket menjalankan aplikasi dalam mode kompatibilitas mundur 16 KB jika kondisi berikut terpenuhi:
- Jika aplikasi memiliki file ELF (dengan ekstensi
.so) dengan penyelarasan segmen LOAD sebesar 4 KB. - Jika APK yang di-zip memiliki file ELF yang tidak dikompresi dan diselaraskan dengan ZIP 4 KB.
Jika pengelola paket telah mengaktifkan mode kompatibilitas mundur 16 KB untuk aplikasi, aplikasi akan menampilkan peringatan saat pertama kali diluncurkan yang menyatakan bahwa aplikasi berjalan dalam mode kompatibilitas mundur 16 KB.
Mode kompatibilitas mundur 16 KB memungkinkan beberapa aplikasi berfungsi, tetapi untuk keandalan dan stabilitas terbaik, aplikasi harus tetap diselaraskan dengan 16 KB.
Di halaman info aplikasi, di bagian Advanced, aktifkan setelan Run app with page size compat mode untuk mengaktifkan atau menonaktifkan mode kompatibilitas mundur 16 KB untuk aplikasi tertentu. Setelan ini hanya terlihat jika perangkat berjalan dengan ukuran halaman 16 KB.
Setelan mode kompatibilitas ukuran halaman
Untuk memaksa kompatibilitas mundur 16 KB diaktifkan untuk setiap aplikasi di perangkat:
adb shell setprop bionic.linker.16kb.app_compat.enabled true
adb shell setprop pm.16kb.app_compat.disabled false
Untuk menonaktifkan kompatibilitas mundur 16 KB secara paksa untuk setiap aplikasi di perangkat:
adb shell setprop bionic.linker.16kb.app_compat.enabled false
adb shell setprop pm.16kb.app_compat.disabled true
Di Android 17, Anda juga dapat menonaktifkan kompatibilitas mundur 16 KB secara paksa untuk setiap aplikasi dan menyebabkan biner yang tidak kompatibel segera dibatalkan:
adb shell setprop bionic.linker.16kb.app_compat.enabled fatal
adb shell setprop pm.16kb.app_compat.disabled true
Tetapkan properti android:pageSizeCompat ke diaktifkan atau dinonaktifkan untuk mengaktifkan atau
menonaktifkan mode kompatibilitas mundur untuk aplikasi tertentu di AndroidManifest.xml-nya. Jika properti ini ditetapkan, aplikasi tidak akan menampilkan peringatan mode kompatibilitas mundur saat diluncurkan.