Android, geçmişte yalnızca 4 KB bellek sayfası boyutlarını desteklemişti. Bu da Android cihazların genellikle sahip olduğu toplam bellek miktarı için sistem belleği performansını optimize etmişti. Android 15'ten itibaren AOSP, 16 KB sayfa boyutu kullanacak şekilde yapılandırılmış cihazları (16 KB cihazlar) destekler. Uygulamanız doğrudan veya bir SDK üzerinden dolaylı olarak NDK kitaplıkları kullanıyorsa uygulamanızı 16 KB'lık cihazlarda çalışacak şekilde yeniden oluşturmanız gerekir.
Cihaz üreticileri daha fazla fiziksel bellek (RAM) içeren cihazlar üretmeye devam ettikçe bu cihazların çoğu, cihazın performansını optimize etmek için 16 KB (ve sonunda daha büyük) sayfa boyutlarını kullanacak. 16 KB sayfa boyutuna sahip cihazlar için destek eklemek, uygulamanızın bu cihazlarda çalışmasını sağlar ve uygulamanızın ilgili performans iyileştirmelerinden yararlanmasına yardımcı olur. Yeniden derlenmeyen uygulamalar, gelecekteki Android sürümlerinde 16 KB'lık cihazlarda çalışmayacaktır.
Uygulamanıza destek eklemenize yardımcı olmak için uygulamanızın etkilenip etkilenmediğini kontrol etme, uygulamanızı yeniden oluşturma (geçerliyse) ve emülatörleri (Android Emulator için Android 15 sistem görüntüleri dahil) kullanarak uygulamanızı 16 KB ortamında test etme hakkında rehberlik sağladık.
Google Play uyumluluk şartı
Uygulamanızın Android'in en yeni sürümlerinde doğru şekilde çalışmasını sağlamak için Android 15 (API düzeyi 35) ve sonraki sürümleri hedefleyen tüm uygulamaların Google Play'deki 64 bit cihazlarda 16 KB'lık bellek sayfası boyutlarını desteklemesi gerekir. 1 Şubat 2027'den itibaren, uygulama güncellemeleriniz 16 KB'lık bellek sayfası boyutlarını desteklemiyorsa bu güncellemeleri yayınlayamazsınız.
Avantajlar ve performans artışları
16 KB sayfa boyutlarıyla yapılandırılan cihazlar, ortalama olarak biraz daha fazla bellek kullanır. Ancak, hem sistem hem de uygulamalar için çeşitli performans iyileştirmeleri sağlar:
- Sistem bellek baskısı altındayken daha düşük uygulama başlatma süreleri: Test ettiğimiz bazı uygulamalarda daha belirgin iyileştirmeler (%30'a varan) ile birlikte ortalama %3, 16 daha düşük
- Uygulama başlatma sırasında güç tüketimi azaltıldı: Ortalama% 4,56 oranında azalma
- Daha hızlı kamera başlatma: Ortalama% 4,48 daha hızlı çalışır durumda başlatma ve ortalama% 6,60 daha hızlı soğuk başlatma
- İyileştirilmiş sistem önyükleme süresi: Ortalama %8 (yaklaşık 950 milisaniye) iyileşme
Bu iyileştirmeler, ilk testlerimizi temel almaktadır ve gerçek cihazlardaki sonuçlar büyük olasılıkla farklılık gösterecektir. Testlerimizi sürdürürken uygulamaların olası kazanımlara ilişkin ek analizler sağlayacağız.
Uygulamanızın etkilenip etkilenmediğini kontrol etme
Uygulamanız yerel kod kullanıyorsa uygulamanızı 16 KB cihazları destekleyecek şekilde yeniden oluşturmanız gerekir. Uygulamanızın yerel kod kullanıp kullanmadığından emin değilseniz APK Analiz Aracı'nı kullanarak yerel kod olup olmadığını belirleyebilir ve ardından bulduğunuz paylaşılan kitaplıklar için ELF segmentlerinin hizalamasını kontrol edebilirsiniz. Android Studio, hizalama sorunlarını otomatik olarak algılamanıza yardımcı olan özellikler de sunar.
Uygulamanızda yalnızca Java programlama dilinde veya Kotlin'de yazılmış kodlar (tüm kitaplıklar veya SDK'lar dahil) kullanılıyorsa uygulamanız 16 KB cihazları zaten destekliyor demektir. Bununla birlikte, uygulama davranışında beklenmedik bir gerileme olmadığını doğrulamak için uygulamanızı 16 KB ortamında test etmenizi öneririz.
Uygulamanız yerel kod kullanıyor mu?
Aşağıdakilerden herhangi biri geçerliyse uygulamanız yerel kod kullanıyordur:
- Uygulamanızda C/C++ (yerel) kod kullanılıyorsa. Uygulamanız Android NDK kullanıyorsa yerel kod kullanıyor demektir.
- Uygulamanız, bunları kullanan üçüncü taraf yerel kitaplıklar veya bağımlılıklarla (ör. SDK'lar) bağlantı kuruyorsa
- Uygulamanız, cihazda yerel kitaplıklar kullanan bir üçüncü taraf uygulama oluşturucu tarafından oluşturulmuş.
APK Analyzer'ı kullanarak yerel kitaplıkları belirleme
APK Analyzer, derlenmiş bir APK'nın çeşitli yönlerini değerlendirmenize olanak tanıyan bir araçtır. Uygulamanızın yerel kod kullanıp kullanmadığını kontrol etmek için (16 KB ile uyumlu olup olmadığına bakılmaksızın):
- Android Studio'yu açın, ardından File > Open'ı (Dosya > Aç) tıklayıp herhangi bir projeyi seçin.
Menü çubuğundan Build > Analyze APK...'yı (Derle > APK'yı analiz et...) tıklayın.
Analiz etmek istediğiniz APK'yı seçin.
Varsa paylaşılan nesne (
.so) dosyalarını barındıranlibklasörüne bakın. Paylaşılan nesne dosyaları varsa uygulamanız yerel kod kullanır. Hizalama sütununda, hizalama sorunları olan dosyalar için uyarı mesajları gösterilir. Paylaşılan nesne dosyası veyalibklasörü yoksa uygulamanız yerel kod kullanmıyor demektir.
Otomatik kontrollerle hizalama sorunlarını tespit etme
Önceden derlenmiş kitaplıklarınız veya APK'larınız 16 KB ile uyumlu değilse Android Studio sizi proaktif olarak uyarır. Hangi kitaplıkların güncellenmesi gerektiğini veya kod değişikliği gerekip gerekmediğini incelemek için APK Analyzer aracını kullanın.
Android Studio'daki Lint, 16 KB'a uygun olmayan yerel kitaplıkları da vurgular.
Paylaşılan kitaplıklar için ELF segmentlerinin hizalamasını kontrol etme
Paylaşılan kitaplıkların ELF segmentlerinin 16 KB ELF hizalaması kullanılarak doğru şekilde hizalandığını doğrulayın.
APK Analyzer'ı kullanma (Önerilir)
Paylaşılan kitaplıklarınızın hizalamasını doğrulamanın en kolay yolu Android Studio'da APK Analyzer'ı kullanmaktır. Paylaşılan bir nesne dosyası 16 KB hizalı değilse Hizalama sütununda bir uyarı mesajı gösterilir.
check_elf_alignment.sh komut dosyasını kullanma (Linux veya macOS)
Linux veya macOS'te geliştirme yapıyorsanız ve komut dosyası kullanmayı tercih ediyorsanız check_elf_alignment.sh komut dosyasını kullanabilirsiniz:
check_elf_alignment.shkomut dosyasını bir dosyaya kaydedin.Komut dosyasını uygulamanızın APK dosyasında çalıştırın:
check_elf_alignment.sh APK_NAME.apkKomut dosyası, tüm
arm64-v8apaylaşılan kitaplıkları içinALIGNEDveyaUNALIGNEDçıkışı verir.arm64-v8aveyax86_64paylaşılan kitaplıklarıUNALIGNEDise bu kitaplıkların paketlemesini güncellemeniz, ardından uygulamanızı yeniden derlemeniz ve bu bölümdeki adımları uygulayarak yeniden test etmeniz gerekir.
Komut satırı araçlarını doğrudan kullanma
ELF segmentlerinin hizalamasını doğrudan komut satırı araçlarını kullanarak kontrol etmek için aşağıdaki adımları uygulayın:
- Android SDK Build-Tools'un 35.0.0 veya sonraki bir sürümünün ve Android NDK'nin, Android Studio'daki SDK Manager veya
sdkmanagerkomut satırı aracı kullanılarak yüklendiğinden emin olun. Uygulamanızın APK dosyasını ayıklayın:
Linux veya macOS
unzip APK_NAME.apk -d /tmp/my_apk_outWindows (PowerShell)
Expand-Archive -Path .\APK_NAME.apk -DestinationPath ~\tmp\my_apk_outAPK dosyanızı çıkardığınız geçici dizinde, paylaşılan nesne (
.so) dosyaları içinlibdizininin içeriğini kontrol edin. Bunlar, APK Analyzer'ı kullanarak yerel kitaplıkları tanımlarken gördüğünüz paylaşılan nesne dosyalarıyla aynıdır. Her paylaşılan nesne dosyasında aşağıdaki komutu çalıştırın:Linux veya 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"Burada
SDK_ROOT_LOCATION, Android SDK'yı yüklediğiniz dizinin yolu,SHARED_OBJECT_FILE, kontrol ettiğiniz paylaşılan nesne dosyasının adı veNDK_VERSION, yüklediğiniz Android NDK'nın sürümüdür (örneğin,28.0.12433566). Kontrol ettiğiniz her dosya için çıkış aşağıdakine benzer: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**14Yük segmentlerinin
2**14değerinden küçük değerlere sahip olmadığından emin olmak için çıkış satırlarını kontrol edin. Yükleme segmentlerinden herhangi biri2**13,2**12veya daha düşük değerlere sahipse bu kitaplıkların paketlemesini güncellemeniz, ardından uygulamanızı yeniden derlemeniz ve bu bölümdeki adımları uygulayarak yeniden test etmeniz gerekir.Ardından, uygulamanızın APK dosyasında
zipalignkomut satırı aracını çalıştırın:Linux veya 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.apkBurada
SDK_ROOT_LOCATION, Android SDK'yı yüklediğiniz dizinin yolu,APK_NAMEise uygulamanızın APK dosyasının adıdır. Tüm paylaşılan kitaplıklar doğru şekilde hizalanmışsa çıkışın son satırında "Doğrulama başarılı" ifadesi yer alır.Doğrulama başarısız olduysa bazı paylaşılan kitaplıkların yeniden hizalanması gerekir. Bu nedenle, bu kitaplıkların paketlemesini güncellemeniz, ardından uygulamanızı yeniden derlemeniz ve bu bölümdeki adımları uygulayarak yeniden test etmeniz gerekir.
RELRO güvenlik işaretini kontrol etme
Modern bağlayıcılar, güvenlik açıklarını azaltmak için Yeniden Konumlandırma Salt Okunur (RELRO) işaretini kullanarak paylaşılan nesne dosyasının yeniden konumlandırma hedef bölümlerini (ör. .got ve .data.rel.ro) dinamik yeniden konumlandırmalar tamamlandıktan sonra salt okunur hale getirir.
Derlemenizde RELRO işaretini etkinleştirin.
GNU_RELRO, sonraki yazılabilir verilerle (.data veya .bss gibi) yazılabilir bir LOAD segmenti paylaştığında GNU_RELRO segmentinin bitiş adresi (VirtAddr + MemSiz) 16 KB hizalı (0x4000) olmalıdır. Aksi takdirde, Android Bağlayıcı GNU_RELRO'nin sonunu içeren 16 KB'lık sayfayı salt okunur olarak işaretlediğinde, aynı 16 KB'lık sayfanın geri kalanında bulunan bitişik yazılabilir veriler de salt okunur hale gelir ve bu verilere yazıldığında uygulama çalışma zamanında segmentasyon hatası (SIGSEGV) ile kilitlenir.
Bu durum genellikle .so dosyası, ilgili işaretler etkinleştirilmeden NDK araç zinciri r27 ve daha eski sürümlerle oluşturulduğunda ortaya çıkar.
APK Analyzer'ı kullanma (Önerilir)
Paylaşılan nesne dosyalarınızın RELRO uyumluluk durumunu doğrudan kontrol etmek için Android Studio'daki APK Analyzer'ı kullanabilirsiniz.
Komut satırı araçlarını kullanma
Hizalamayı manuel olarak kontrol etmeyi tercih ediyorsanız veya süreci otomatikleştirmeniz gerekiyorsa aşağıdaki adımları uygulayın:
1. adım: Program başlıklarını inceleyin
Her paylaşılan nesne dosyasında aşağıdaki komutu çalıştırın (Linux'ta darwin-x86_64 yerine linux-x86_64 yazın):
Linux veya 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'
RELRO segmenti varsa GNU_RELRO dizesi yazdırılır.
2. adım: RELRO için 16 KB uyumluluğunu doğrulayın
Aşağıdaki koşullardan herhangi biri karşılanıyorsa paylaşılan nesne dosyası RELRO açısından 16 KB ile uyumludur:
- Program başlıklarında
GNU_RELROsegmenti yok. GNU_RELRObitiş adresi 16 KB hizalıdır: Sanal adresinin (VirtAddr) ve bellek boyutunun (MemSiz) toplamı 16 KB'a (0x4000) bölündüğünde sıfır kalanını (modulo) verir:(VirtAddr + MemSiz) % 0x4000 == 0.- Aynı
LOADsegmentindeGNU_RELROöğesinden sonra yazılabilir veri yok:GNU_RELRO, içinde bulunduğuLOADsegmentinin geri kalanının tamamını kaplar (yaniLOAD.VirtAddr + LOAD.MemSiz == RELRO.VirtAddr + RELRO.MemSiz). Bu nedenle, yazılabilir.dataveya.bssbölümleri sondaki sayfayı paylaşmaz.
Örnekler
Aşağıdaki örneklerde, farklı GNU_RELRO yapılandırmaları için llvm-readelf çıkışının nasıl değerlendirileceği gösterilmektedir.
1. örnek: Hizalanmamış .so dosyası (uygun değil)
Bu örnekte GNU_RELRO, sonraki yazılabilir verilerle bir RW LOAD segmentini paylaşıyor ve bitiş adresi 0x4000'ün katı değil:
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
- Formül:
(VirtAddr + MemSiz) % 0x4000 == 0 - Sonuç:
(0xdfaf0 + 0x01510) % 0x4000 = 0xE1000 % 0x4000 == 0x1000
0x1000 sıfır olmadığından ve içeren LOAD segmenti 0xE1000 sonrasında devam ettiğinden (0xdfaf0 + 0x04510 = 0xE4000 adresinde sona erer) bu .so dosyası 16 KB ile uyumlu değildir. 16 KB'lık bir cihazda bağlayıcı, RELRO koruma aralığını 16 KB'lık sayfa sınırlarına yuvarlayarak 0xDC000 (önceki sayfa sonu) ile 0xE4000 arasını salt okunur olarak işaretler. Ancak .so dosyasının yazılabilir .data ve .bss bölümleri 0xE1000 ile 0xE4000 arasındaki alt aralıkta yer aldığından, çalışma zamanında değiştirildiğinde segmentasyon hatası oluşur. Bu .so dosyasını, Uygulamanızı 16 KB ELF hizalaması kullanarak derleme bölümünde açıklandığı şekilde yeniden derleyin.
2. örnek: RELRO segmentiyle hizalanmış .so dosyası (Uyumlu)
Bu örnekte, GNU_RELRO segmentinin sonu 16 KB'lık bir sayfa sınırına denk geliyor:
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
- Formül:
(VirtAddr + MemSiz) % 0x4000 == 0 - Sonuç:
(0xdfaf0 + 0x00510) % 0x4000 = 0xE0000 % 0x4000 == 0
Kalan 0 olduğu için RELRO koruması 0xE0000 sayfa sınırında düzgün bir şekilde sona erer ve 0xE0000 adresinden başlayan yazılabilir veriler etkilenmez.
3. örnek: RELRO segmenti olmayan .so dosyası (Uyumlu)
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
Bu .so dosyasında GNU_RELRO segmenti olmadığından RELRO sayfa sınırı sorunları geçerli değildir (ancak güvenlik için RELRO'nun etkinleştirilmesi önerilir).
4. örnek: Kendi LOAD segmentinde GNU_RELRO (uygun)
Bu örnekte GNU_RELRO, 16 KB sınırında bitmiyor ancak aynı LOAD segmentinde yazılabilir veri bulunmadığı için
yine de uyumludur:
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
- Formül:
(VirtAddr + MemSiz) % 0x4000 == 0 - Sonuç:
(0x4680 + 0x0980) % 0x4000 = 0x5000 % 0x4000 == 0x1000
0x1000 sıfır olmasa da bu .so dosyası 16 KB ile uyumludur.
GNU_RELRO ile onu içeren LOAD segmenti (ikinci LOAD girişi) karşılaştırıldığında, her ikisinin de VirtAddr 0x4680 adresinde başladığı ve tam olarak aynı adreste (0x4680 + 0x0980 = 0x5000) bittiği görülür.
LOAD segmentinin tamamı yalnızca RELRO verileri içerdiğinden 0x5000 ile 0x8000 arasındaki alt aralıkta yazılabilir .data veya .bss verisi yoktur (kitaplıkta RELRO olmayan yazılabilir veri yoktur veya sonraki yazılabilir LOAD segmenti 0x8000 ya da daha ilerideki ayrı bir 16 KB sayfa sınırında başlar). Bağlayıcının salt okunur koruması, yazılabilir verilerle çakışmaz. Bu nedenle segmentasyon hatası oluşmaz.
Uygulamanızı 16 KB cihazları destekleyecek şekilde derleme
Uygulamanız yerel kod kullanıyorsa uygulamanızın 16 KB cihazları desteklediğinden emin olmak için aşağıdaki bölümlerde açıklanan adımları tamamlayın:
- Paylaşılan kitaplıklarınızın paketlemesini güncelleme
- Uygulamanızı 16 KB ELF hizalaması kullanarak derleme
- Kodu düzeltme ve çalışma zamanı sorunlarını çözme
- Özel bellek ayırıcıları optimize etme (varsa)
- SDK'ların 16 KB desteğini kontrol etme
Paylaşılan kitaplıklarınızın paketlemesini güncelleme
AGP 8.5.1 veya daha yeni bir sürüme yükseltin ve sıkıştırılmamış paylaşılan kitaplıkları kullanın.
ZIP hizalamasını doğrulamak için bundletool aracını kullanın.
Paketinizin hizalamasını görmek için şunları kullanın:
bundletool dump config --bundle=<my .aab> | grep alignment
PAGE_ALIGNMENT_16K ifadesini görüyorsanız paketiniz 16 KB ZIP hizalaması istiyor demektir. PAGE_ALIGNMENT_4K ifadesini görüyorsanız bu, bu AAB'den oluşturulan APK'nın, ZIP dosyasında 4 KB hizalanmış .so dosyaları içermesini sağlar.
AGP 8.5.1 veya sonraki sürümler
16 KB cihazlar, sıkıştırılmamış paylaşılan kitaplıklarla birlikte gelen uygulamaların 16 KB zip ile uyumlu bir sınırda hizalanmasını gerektirir. Bunun için Android Gradle eklentisi (AGP) 8.5.1 veya sonraki bir sürüme yükseltmeniz gerekir. Yükseltme işlemiyle ilgili ayrıntılar için Android Gradle eklentisi Yükseltme Asistanı bölümüne bakın.
AGP sürümü 8.5 veya daha eski
AGP'yi 8.5.1 veya sonraki bir sürüme yükseltemiyorsanız alternatif olarak sıkıştırılmış paylaşılan kitaplıkları kullanmaya geçebilirsiniz. Uygulamanızı paketlerken Gradle'ın paylaşılan kitaplıklarınızı sıkıştırması için Gradle yapılandırmanızı güncelleyin. Böylece, hizalanmamış paylaşılan kitaplıklarla ilgili uygulama yükleme sorunlarını önleyebilirsiniz.
Modern
build.gradle dosyanıza aşağıdaki seçeneği ekleyin:
android {
...
packagingOptions {
jniLibs {
useLegacyPackaging true
}
}
}
Kotlin
build.gradle.kts dosyanıza aşağıdaki seçeneği ekleyin:
android {
...
packagingOptions {
jniLibs {
useLegacyPackaging = true
}
}
}
AGP 8.0 veya daha eski sürümler
8.0 veya daha eski bir AGP sürümü kullanıyorsanız gradle.properties dosyanızda uygulama paketleri için sıkıştırılmamış yerel kitaplık seçeneğini de devre dışı bırakmanız gerekir:
android.bundle.enableUncompressedNativeLibs=false
Uygulamanızı 16 KB ELF hizalaması kullanarak derleme
16 KB cihazlarda uygulamanızın çalışması için paylaşılan kitaplıkların ELF segmentlerinin 16 KB ELF hizalaması kullanılarak doğru şekilde hizalanması gerekir.
Oyun geliştiricileri için: Oyununuz Unity oyun motoru üzerinde çalışıyorsa Unity kılavuzuna bakın. Oyununuz Unreal oyun motoru üzerinde çalışıyorsa Unreal kılavuzuna bakın. Yerel oyun motorları için bu kılavuzu kullanmaya devam edin.
Uygulamanızı 16 KB ELF hizalaması kullanarak derlemek için kullandığınız Android NDK sürümüne bağlı olarak aşağıdaki bölümlerden birindeki adımları tamamlayın.
Android NDK r28 ve sonraki sürümler
NDK sürüm r28 ve sonraki sürümler, varsayılan olarak 16 KB ile uyumlu olacak şekilde derlenir.
Android NDK r27 ve önceki sürümler
Android NDK r27 veya daha eski sürümlerle 16 KB uyumlu paylaşılan kitaplıkların derlenmesini desteklemek için aşağıdaki bağlayıcı işaretlerini kullanın:
-Wl,-z,max-page-size=16384
-Wl,-z,common-page-size=16384
Derleme sistemi yapılandırma dosyalarınızı şu şekilde güncelleyebilirsiniz:
ndk-build
ndk-build kullanıyorsanız 16 KB ELF hizalamasını etkinleştirmek için Android.mk dosyanızı güncelleyin:
LOCAL_LDFLAGS += -Wl,-z,max-page-size=16384 -Wl,-z,common-page-size=16384
CMake
CMake kullanıyorsanız 16 KB ELF hizalamasını etkinleştirmek için CMakeLists.txt dosyanızı güncelleyin.
target_link_options(${CMAKE_PROJECT_NAME} PRIVATE
"-Wl,-z,max-page-size=16384"
"-Wl,-z,common-page-size=16384"
)
Kodu düzeltme ve çalışma zamanı sorunlarını çözme
Uygulamanız 16 KB uyumlu olsa bile kodunuzda bir cihazın belirli bir sayfa boyutu kullandığı varsayılıyorsa uygulamanız hatalarla karşılaşabilir. Bunu önlemek için aşağıdaki adımları uygulayın:
PAGE_SIZEsabitine referans veren tüm sabit kodlu bağımlılıkları veya kod mantığınızda bir cihazın sayfa boyutunun 4 KB (4096) olduğunu varsayan örnekleri kaldırın.Bunun yerine
getpagesize()veyasysconf(_SC_PAGESIZE)kullanın.mmap()ve sayfa hizalı bağımsız değişkenler gerektiren diğer API'lerin kullanımlarını bulun ve gerektiğinde alternatiflerle değiştirin.
Bazı durumlarda, uygulamanız temel sayfa boyutuna bağlı olmayan uygun bir değer olarak PAGE_SIZE kullanıyorsa bu durum, uygulamanızın 16 KB modunda kullanıldığında bozulmasına neden olmaz. Ancak bu değer, mmap olmadan MAP_FIXED ile çekirdeğe iletilirse çekirdek yine de tam bir sayfa kullanır ve bu da bir miktar bellek israfına neden olur. Bu nedenle, NDK r27 ve sonraki sürümlerde 16 KB modu etkinleştirildiğinde PAGE_SIZE tanımlanmaz.
Uygulamanız PAGE_SIZE değişkenini bu şekilde kullanıyor ve bu değeri hiçbir zaman doğrudan çekirdeğe iletmiyorsa PAGE_SIZE değişkenini kullanmak yerine, başka amaçlarla kullanıldığını ve gerçek bir bellek sayfasını yansıtmadığını belirten yeni bir ada sahip yeni bir değişken oluşturun.
Özel bellek ayırıcıları optimize etme
16 KB sistemlerde, işletim sisteminin tahsis ettiği en küçük fiziksel bellek birimi, 4 KB sistemlere göre dört kat daha büyüktür. Özel bir ayırıcı 4 KB'lık varsayımlara göre tasarlandıysa küçük nesneleri birden fazla 16 KB'lık sayfaya dağıtabilir ve boş belleği gereksiz yere tutabilir. Bu durum, fiziksel bellek kullanımını (RSS) önemli ölçüde artırabilir ve sıkıştırılmış takas (ZRAM) verimliliğini düşürebilir.
Kodunuz kendi bellek havuzlarını yönetiyorsa aşağıdaki önerileri uygulayın:
1. Bellekte yer açmak için sabit kodlu bayt eşikleri kullanmaktan kaçının.
Birçok ayırıcı, madvise(MADV_DONTNEED) kullanarak belleği işletim sistemine ne zaman geri vereceğine karar vermek için sabit bayt sınırları kullanır (ör. yalnızca etkin nesneler 8 KB'tan az yer kaplıyorsa belleği serbest bırak).
16 KB'lık bir sistemde, 16 baytlık tek bir canlı nesne bile 16 KB'lık bir sayfanın tamamını (8 KB'tan büyük) sabitler. Sonuç olarak, serbest bırakma eşiğine hiçbir zaman ulaşılmaz ve ayırıcı, çevredeki kullanılmayan belleği hiçbir zaman çekirdeğe döndürmez.
Yapılması gerekenler: Sayfa yayınlama buluşsal yöntemleri için hiçbir zaman sabit kodlu bayt sabitleri kullanmayın.
sysconf(_SC_PAGESIZE) kullanarak çalışma zamanında gerçek sayfa boyutuna göre sürüm eşiklerini dinamik olarak ölçeklendirin.
2. Önce kullanılmış sayfaları doldurma (yoğunluk öncelikli tahsis)
Ayırıcı, belleği ilk giren ilk çıkar (FIFO) veya sırayla dağıtırsa yeni ayırmalar, kısmen doldurulmuş birçok 16 KB'lık sayfaya dağıtılır. Sayfadaki tek bir nesne, 16 KB'ın tamamını fiziksel RAM'de tutar.
Yapılması gerekenler: Boş veya az kullanılan sayfalara dokunmadan önce her zaman en dolu (en yoğun) sayfadan veya bloktan yeni nesneler tahsis edin. Yeni ayırmaları zaten kirli olan sayfalarda yoğunlaştırmak, az kullanılan sayfaların doğal olarak sıfır etkin nesneye boşalmasını sağlar. Böylece 16 KB'lık sayfanın tamamı işletim sistemine bırakılabilir.
3. Bellek havuzlarını 16 KB'a hizalayın ve havuz boyutlarını orta düzeyde tutun.
4 KB sistemler için tasarlanmış çok sayfalı aralıklar, 16 KB çekirdeklerde aşırı miktarda serbest bırakılmamış bellek boşluğu barındırabilir. Ayrıca, 16 KB'a eşit olarak bölünmeyen boyut sınıfları, her sayfanın sonunda parçalanmaya neden olur.
Yapılması gerekenler:
- Tüm bellek havuzlarının, slab sınırlarının ve arabellek hizalamalarının, çalışma zamanı sayfa boyutunun tam katları olduğundan emin olun.
- Boşta kalan belleği kaplayan aşırı büyük slab'lerin tahsis edilmesini önlemek için küçük nesne sınıflarının çok sayfalı span boyutlarını yeniden değerlendirin.
4. Önbelleğe alınmış büyük arabellekler için fiziksel belleği hemen serbest bırakma
Özel ayırıcılar, mmap veya munmap sistem çağrılarının ek yükünü ödemeden yeniden kullanılabilmeleri için genellikle büyük arabellekleri (> 64 KB) bellek içi havuzda önbelleğe alır. Ancak bu kirli arabellekleri bellekte tutmak, çıkarma zamanlayıcısını beklerken megabaytlarca fiziksel RAM'i boşa harcar.
Yapılması gerekenler: Sanal bellek adres aralığını hızlı yeniden kullanım için ayrılmış olarak tutun ancak bir arabelleği önbelleğe döndürürken hemen madvise(..., MADV_DONTNEED) veya madvise(..., MADV_FREE) işlevini çağırın. İşletim sistemi, fiziksel RAM'i hemen geri alır. Uygulamanız ise sanal adresi yeniden tahsis etmeden anında tekrar kullanabilir.
5. ZRAM sıkıştırması için tahsisat yerine boşaltma sırasında belleği sıfırlama
Android, arka plan uygulamalarını bellekte tutmak için sıkıştırılmış takas (ZRAM) kullanır. 16 KB'lık cihazlarda, bir sayfada tek bir canlı nesne bile varsa 16 KB'lık sayfanın tamamı yerleşik olarak kalır veya ZRAM'e taşınır. Sayfanın daha önce boşaltılmış kısımlarında kalan çöp veriler (ör. eski işaretçiler ve dizeler) iyi sıkıştırılamaz.
Ayırıcınız belleği sıfırlıyorsa (ör. güvenlik veya sıfır başlatılmış ayırmalar için) ayırma sırasında değil, ayırmayı kaldırma (free()) sırasında sıfırlamayı düşünün:
- Sabitlenmiş sayfaların maliyeti daha düşüktür: Kısmen dolu 16 KB'lık sayfalardaki boş bellek, ZRAM'de neredeyse sıfıra kadar sıkıştırılır. Bu nedenle, sabitlenmiş sayfalar fiziksel takas alanını boşa harcamaz.
- Minimum önbellek ek yükü:
free()çağrıldığında bellek CPU önbelleğinde zaten sıcaktır. Bu sayede, daha sonra önbellekte yok hatası alınmaz.
Önerilerin özeti
| Alan | Öneri | Beklenen etki |
|---|---|---|
| Temizleme eşikleri | sysconf(_SC_PAGESIZE) kullanarak sürüm eşiklerini dinamik olarak ölçeklendirin. |
Sürüm mantığının kalıcı olarak kilitlenmesini önler. |
| Tahsis sırası | Öncelikle en yoğun (neredeyse dolu) sayfadan veya bloktan tahsis edin. | Etkin nesneleri bir araya getirerek yerleşik belleği (RSS) azaltır. |
| Aralık boyutlandırma | Boyut sınıflarını 16 KB'lık katlara hizalayın ve aşırı büyük slab'lerden kaçının. | Kuyruk sayfası parçalanmasını ortadan kaldırır ve bellek boşluğunu azaltır. |
| Arabellek önbellekleri | Büyük arabellekleri önbelleğe alırken hemen madvise(MADV_DONTNEED) yöntemini çağırın. |
Hızlı sanal yeniden kullanımı korurken boşta kalan RAM şişmesini ortadan kaldırır. |
| Takas/ZRAM | Belleği tahsisat sırasında değil, free() sırasında sıfırlayın. |
ZRAM sıkıştırma oranlarını iyileştirerek sabitlenmiş sayfaların maliyetini azaltır. |
SDK'ların 16 KB desteğini kontrol etme
Birçok SDK, özellikle kendiniz oluşturursanız veya son önceden derlenmiş sürümleri kullanırsanız 16 KB sayfa boyutlarıyla uyumludur. Ancak bazı önceden derlenmiş SDK'lar veya SDK sürümleri 16 KB ile uyumlu olmadığından, 16 KB ile hangi sürümün kullanılacağını belirlemek için her SDK sağlayıcının web sitesini kontrol etmeniz gerekir.
Uygulamanızı 16 KB ortamında test edin
Uygulamanızı 16 KB cihazları destekleyecek şekilde derledikten sonra, uygulamanızda herhangi bir gerileme olup olmadığını görmek için uygulamanızı 16 KB ortamında test etmeniz gerekir. Bunu yapmak için aşağıdaki adımları uygulayın:
Android 15 SDK veya sonraki bir sürümü ayarlayın.
Aşağıdaki test ortamlarından birini oluşturun:
- Android Emulator'ı 16 KB tabanlı bir Android 15 sistem görüntüsüyle ayarlama
- ARM64'te 16 KB sayfa boyutuna sahip Cuttlefish'i kullanma
- x86-64'te 16 KB sayfa boyutuna sahip Cuttlefish'i simüle etme
- Geliştirici seçeneklerini kullanarak bir cihazda 16 KB modunu etkinleştirme
- Desteklenen cihazlarda 16 KB'lık Samsung Remote Test Lab'i kullanma
Test cihazınızı başlatın, ardından 16 KB'lık bir ortam kullandığını doğrulamak için aşağıdaki komutu çalıştırın:
adb shell getconf PAGE_SIZEKomut,
16384değerini döndürmelidir.Uygulamanızın 16 KB uyumlu olduğunu doğrulamak için aşağıdaki
zipalignkomutunu çalıştırın. APK_NAME, uygulamanızın APK dosyasının adıdır:zipalign -c -P 16 -v 4 APK_NAME.apkBelirli sayfa boyutlarına referans veren kod örneklerini değiştirerek etkilenebilecek alanlara odaklanıp uygulamanızı kapsamlı bir şekilde test edin.
Android Emulator'ı 16 KB tabanlı sistem görüntüsüyle ayarlama
Android Emulator'ı kullanarak 16 KB'lık bir ortam oluşturmak için aşağıdaki adımları uygulayın:
- Android Studio'da Tools > SDK Manager'ı (Araçlar > SDK Manager) tıklayın.
SDK Platforms (SDK Platformları) sekmesinde Show Package Details'ı (Paket Ayrıntılarını Göster) seçin, ardından Android VanillaIceCream veya daha yeni bir sürüm bölümünü genişletin ve oluşturmak istediğiniz sanal cihazlara bağlı olarak aşağıdaki emülatör sistem görüntülerinden birini veya her ikisini seçin:
- Google API'leri Deneysel 16 KB Sayfa Boyutu ARM 64 v8a Sistem Resmi
- Google API'leri Deneysel 16 KB Sayfa Boyutu Intel x86_64 Atom Sistem Görüntüsü
Seçtiğiniz sistem görüntülerini indirmek için Apply > OK'i (Uygula > Tamam) tıklayın.
Android 15 için sanal cihaz oluşturma adımlarını uygulayın ve sistem görüntüsü seçmeniz istendiğinde indirdiğiniz 16 KB sistem görüntüsünü seçin. Otomatik olarak önerilmezse 16 KB sistem görüntüsünü Diğer Görüntüler sekmesinde bulabilirsiniz.
Emülatörü başlatma
Android Emulator'ı ve sanal cihazları ayarlamayı tamamladıktan sonra emülatörü hedef cihaz menüsünden veya komut satırından başlatın.
Geliştirici seçeneklerini kullanarak bir cihazda 16 KB modunu etkinleştirme
Cihazı 16 KB modunda başlatmak için 16 KB sayfa boyutuyla başlat geliştirici seçeneğini etkinleştirin.
Android 15'in QPR sürümlerinde, cihazı 16 KB modunda başlatmak ve cihaz üzerinde test yapmak için belirli cihazlarda bulunan geliştirici seçeneğini kullanabilirsiniz. Geliştirici seçeneğini kullanmadan önce Ayarlar > Sistem > Yazılım güncellemeleri'ne gidip varsa güncellemeleri uygulayın.
Bu geliştirici seçeneği aşağıdaki cihazlarda kullanılabilir:
Pixel 8 ve 8 Pro (Android 15 QPR1 veya sonraki sürümlerle)
Pixel 8a (Android 15 QPR1 veya sonraki sürümler)
Pixel 9, 9 Pro ve 9 Pro XL (Android 15 QPR2 veya sonraki bir sürüm yüklü)
Pixel 9a (Android 16 veya sonraki sürümler)
16 KB geriye dönük uyumluluk modu
Sayfa boyutu uyumluluk modunda uyarı
16 KB geriye dönük uyumluluk seçeneği, cihaz 16 KB çekirdek çalıştırırken kullanılabilir. Paket yöneticisi, aşağıdaki koşullar karşılandığında uygulamayı 16 KB geriye dönük uyumluluk modunda çalıştırır:
- Uygulamada, LOAD segment hizalaması 4 KB olan ELF dosyaları (
.souzantılı) varsa - Sıkıştırılmış APK'da 4 KB ZIP uyumlu, sıkıştırılmamış ELF dosyaları varsa
Paket yöneticisi bir uygulama için 16 KB geriye dönük uyumluluk modunu etkinleştirdiyse uygulama ilk başlatıldığında 16 KB geriye dönük uyumluluk modunda çalıştığını belirten bir uyarı gösterir.
16 KB geriye dönük uyumluluk modu bazı uygulamaların çalışmasına olanak tanır ancak en iyi güvenilirlik ve kararlılık için uygulamaların yine de 16 KB ile uyumlu olması gerekir.
Uygulama bilgileri sayfasındaki Gelişmiş bölümünde, belirli bir uygulama için 16 KB geriye dönük uyumluluk modunu etkinleştirmek veya devre dışı bırakmak üzere Uygulamayı sayfa boyutu uyumluluk moduyla çalıştır ayarını açın ya da kapatın. Bu ayar yalnızca cihaz 16 KB sayfa boyutuyla çalışırken görünür.
Sayfa boyutu uyumluluk modu ayarı
Cihazdaki her uygulama için 16 KB geriye dönük uyumluluğu zorunlu kılmak istiyorsanız:
adb shell setprop bionic.linker.16kb.app_compat.enabled true
adb shell setprop pm.16kb.app_compat.disabled false
Cihazdaki her uygulama için 16 KB geriye dönük uyumluluğu zorunlu olarak devre dışı bırakmak istiyorsanız:
adb shell setprop bionic.linker.16kb.app_compat.enabled false
adb shell setprop pm.16kb.app_compat.disabled true
Android 17'de, her uygulama için 16 KB geriye dönük uyumluluğu zorunlu olarak devre dışı bırakabilir ve uyumsuz ikili dosyaların hemen iptal edilmesine neden olabilirsiniz:
adb shell setprop bionic.linker.16kb.app_compat.enabled fatal
adb shell setprop pm.16kb.app_compat.disabled true
Belirli bir uygulamanın AndroidManifest.xml dosyasında geriye dönük uyumluluk modunu etkinleştirmek veya devre dışı bırakmak için android:pageSizeCompat özelliğini etkin ya da devre dışı olarak ayarlayın. Bu özellik ayarlandığında uygulama, başlatılırken geriye dönük uyumluluk modu uyarıları göstermez.