16 KB sayfa boyutlarını destekleme

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 koşulu

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 bellek sayfası boyutlarını desteklemesi gerekir. 1 Şubat 2027'den itibaren, uygulama güncellemeleriniz 16 KB bellek sayfası boyutlarını desteklemiyorsa bu güncellemeleri yayınlayamazsınız.

Google Play Console'da, uygulama güncellemelerinin 1 Şubat 2027'ye kadar 16 KB'lık bellek sayfası boyutlarını desteklemesi gerektiğini belirten uyarı
Şekil 1. Google Play Console uyumluluk uyarısı.

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ızda yerel kod kullanılıyor:

  • 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ıklara veya bağımlılıklara (ör. SDK'lar) bağlanıyor.
  • Uygulamanız, cihazda yerel kitaplıklar kullanan üçüncü taraf bir uygulama oluşturucu tarafından geliştirilmiştir.

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):

  1. Android Studio'yu açın, ardından Dosya > Aç'ı tıklayın ve herhangi bir projeyi seçin.
  2. Menü çubuğundan Build > Analyze APK...'yı (Derle > APK'yı analiz et...) tıklayın.

    APK Analyzer'ı başlatmak için Studio Build menü seçeneği
  3. Analiz etmek istediğiniz APK'yı seçin.

  4. Varsa paylaşılan nesne (.so) dosyalarını barındıran lib klasörüne bakın. Paylaşılan nesne dosyaları varsa uygulamanız yerel kod kullanır. Hizalama sütununda, hizalama sorunları olan tüm dosyalarla ilgili uyarı mesajları gösterilir. Paylaşılan nesne dosyası yoksa veya lib klasörü yoksa uygulamanız yerel kod kullanmıyordur.

    Paylaşılan nesne dosyalarının mevcut olduğunu gösteren APK Analyzer görünümü

Otomatik kontrollerle uyumluluk 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.

Studio'da bir projedeki hizalama sorunlarıyla ilgili uyarı bildirimleri

Android Studio'daki Lint, 16 KB'a uygun olmayan yerel kitaplıkları da vurgular.

Studio linter'ın, hizalanmamış yerel kitaplıkla ilgili uyarısı

Paylaşılan kitaplıklar için ELF segmentlerinin hizalamasını kontrol etme

Tüm paylaşılan kitaplıklar için, paylaşılan kitaplıkların ELF segmentlerinin 16 KB ELF hizalaması kullanılarak düzgün şekilde hizalandığını doğrulayın. Linux veya macOS'te geliştirme yapıyorsanız aşağıdaki bölümde açıklandığı gibi check_elf_alignment.sh komut dosyasını kullanabilirsiniz. Komut satırı araçlarını doğrudan da kullanabilirsiniz.

check_elf_alignment.sh komut dosyasını kullanma (Linux veya macOS)

check_elf_alignment.sh komut dosyasını kullanarak ELF segmentlerinin hizalamasını kontrol etmek için aşağıdaki adımları uygulayın:

  1. check_elf_alignment.sh komut dosyasını bir dosyaya kaydedin.

  2. Komut dosyasını uygulamanızın APK dosyasında çalıştırın:

    check_elf_alignment.sh APK_NAME.apk
    

    Komut dosyası, tüm arm64-v8a paylaşılan kitaplıkları için ALIGNED veya UNALIGNED çıkışı verir.

  3. UNALIGNED olan arm64-v8a veya x86_64 paylaşılan kitaplıklar varsa 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:

  1. Android SDK Build-Tools 35.0.0 veya sonraki bir sürümün ve Android NDK'nin Android Studio'daki SDK Manager veya sdkmanager komut satırı aracı kullanılarak yüklendiğinden emin olun.
  2. Uygulamanızın APK dosyasını ayıklayın:

    Linux veya macOS

    unzip APK_NAME.apk -d /tmp/my_apk_out
    

    Windows (PowerShell)

    Expand-Archive -Path .\APK_NAME.apk -DestinationPath ~\tmp\my_apk_out
    
  3. APK dosyanızı çıkardığınız geçici dizinde, paylaşılan nesne (.so) dosyaları için lib dizininin 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 LOAD
    

    Windows (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ı ve NDK_VERSION, yüklediğiniz Android NDK'nın sürümüdür (örneğin, 28.0.12433566). Çıktı, kontrol ettiğiniz her dosya için aşağıdakine benzer bir şekilde görünür:

    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**14
    
  4. Yükleme segmentlerinin 2**14 değerinden küçük değerler içermediğinden emin olmak için çıkış satırlarını kontrol edin. Yükleme segmentlerinden herhangi biri 2**13, 2**12 veya 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.

  5. Ardından, uygulamanızın APK dosyasında zipalign komut 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.apk
    

    Windows (PowerShell)

    SDK_ROOT_LOCATION\Android\sdk\build-tools\35.0.0\zipalign.exe -v -c -P 16 4 APK_NAME.apk
    

    Burada SDK_ROOT_LOCATION, Android SDK'yı yüklediğiniz dizinin yolu, APK_NAME ise uygulamanızın APK dosyasının adıdır. Tüm paylaşılan kitaplıklar doğru şekilde hizalanmışsa çıktını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

Güvenlik açıklarından yararlanmayı azaltmak için modern bağlayıcılar, yüklemeden sonra paylaşılan nesne dosyasının yeniden konumlandırma bölümlerini salt okunur hale getirmek üzere Relocation Read-Only (RELRO) işaretini kullanır. Derlemenizde RELRO işaretini etkinleştirin.

Başlangıç adresi ile segment boyutu (MemSize) 16 KB ile uyumlu olmayan bir RELRO bölümü, çalışma zamanında segmentasyon hatasıyla uygulamayı kilitler. Bu durum, .so dosyası ilgili işaretler etkinleştirilmeden NDK araç zinciri r27 ve daha eski sürümlerle oluşturulduysa ortaya çıkar.

Her paylaşılan nesne dosyasında (Linux veya macOS) aşağıdaki komutu çalıştırın:

SDK_ROOT_LOCATION/Android/sdk/ndk/NDK_VERSION/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-readelf -Wl SHARED_OBJECT_FILE.so | grep 'RELRO\|Type'

RELRO segmenti varsa GNU_RELRO dizesi yazdırılır.

Ardından, sanal uzaklık adresini (VirtAddr) segment bellek boyutuyla (MemSiz) toplayıp 16 KB'a (0x4000) bölerek RELRO segment hizalamasını kontrol edin. Kalan (modulo) sıfırsa RELRO segmenti 16 KB hizalıdır.

Hizalanmamış bir .so dosyası örneği:

Type           Offset   VirtAddr           PhysAddr           FileSiz MemSiz  Flg Align  
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 bu .so dosyası 16 KB ile uyumlu değildir. DC000 (önceki sayfa sonu) ile E4000 arasındaki RELRO koruma aralığı salt okunurdur ancak Android Bağlayıcı, E1000 ile E4000 arasındaki alt aralığın yazılabilir olmasını bekler. Bu da segmentasyon hatasına neden olur. Bu durumda, Uygulamanızı 16 KB ELF hizalaması kullanarak derleme bölümünde açıklandığı şekilde .so dosyasını yeniden derleyin.

RELRO segmenti içeren hizalanmış bir .so dosyası örneği:

Type           Offset   VirtAddr           PhysAddr           FileSiz MemSiz  Flg Align
GNU_RELRO      0x0cfaf0 0x00000000000dfaf0 0x00000000000dfaf0 0x01510 0x00510 R   0x1  

Aşağıda, RELRO segmenti olmayan bir .so dosyası örneği verilmiştir:

Type           Offset   VirtAddr           PhysAddr           FileSiz MemSiz  Flg Align

Bu, RELRO segmenti olmayan, 16 KB ile uyumlu bir .so dosyasıdır.

GNU_RELRO öğesinin kendi LOAD segmentinde olduğu hizalanmış bir .so dosyası örneğini aşağıda bulabilirsiniz:

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.

Modulo formülü, GNU_RELRO sonraki yazılabilir verilerle (ör. .data veya .bss) bir LOAD segmenti paylaştığında geçerlidir.

GNU_RELRO öğesinin kendi LOAD segmentinde olup olmadığını kontrol etmek için llvm-readelf -Wl komutunu çalıştırıp grep 'LOAD\|RELRO\|Type' ile filtreleyerek program başlıklarını inceleyin. GNU_RELRO öğesinin VirtAddr ve MemSiz değerlerini, kapsayan LOAD segmentiyle karşılaştırın. Bu örnekte her ikisinde de VirtAddr 0x4680 ve MemSiz 0x0980 var.

LOAD segmentinin tamamı yalnızca RELRO verilerini içerdiğinden, 0x5000 ile 0x8000 arasındaki alt aralıkta yazılabilir veri yoktur. Ayrıca, sonraki tüm yazılabilir LOAD segmentler ayrı bir 16 KB sayfa sınırında (0x8000 veya ötesinde) 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:

  1. Paylaşılan kitaplıklarınızın paketlemesini güncelleme
  2. Uygulamanızı 16 KB ELF hizalaması kullanarak derleme
  3. Kodu düzeltme ve çalışma zamanı sorunlarını çözme
  4. Özel bellek ayırıcıları optimize edin (varsa)
  5. 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.

Fermuar hizalamasını doğrulamak için bundletool kullanma

Paketinizin hizalamasını görmek için şunları kullanın:

bundletool dump config --bundle=<my .aab>  | grep alignment

PAGE_ALIGNMENT_16K simgesini görüyorsanız paketinizin 16 KB'lık zip hizalaması istediğini anlarsınız. PAGE_ALIGNMENT_4K simgesini görüyorsanız bu, bu AAB'den oluşturulan APK'nın zip dosyasında 4 KB'lık .so dosyaları olmasını sağlar.

AGP 8.5.1 veya daha yeni bir sürüm

16 KB cihazlar, sıkıştırılmamış paylaşılan kitaplıklarla birlikte gelen uygulamaların bunları 16 KB zip ile uyumlu bir sınırda hizalaması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 daha yeni bir sürüme yükseltemiyorsanız alternatif olarak sıkıştırılmış paylaşılan kitaplıkları kullanmaya geçebilirsiniz. Hizalanmamış paylaşılan kitaplıklarla ilgili uygulama yükleme sorunlarını önlemek için Gradle yapılandırmanızı, uygulamanızı paketlerken paylaşılan kitaplıklarınızı sıkıştıracak şekilde güncelleyin.

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 uyumluluğu kullanarak derleyin

16 KB'lık cihazlarda uygulamanızın çalışması için paylaşılan kitaplıkların ELF segmentlerinin 16 KB ELF uyumluluğu kullanılarak uygun şekilde uyumlu hale getirilmesi 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ılavuzla devam edin.

Uygulamanızı 16 KB ELF uyumuyla 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'nın r27 veya daha eski bir sürümüyle 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 ile uyumlu olsa bile kodunuzda bir cihazın belirli bir sayfa boyutu kullandığı varsayılıyorsa uygulamanızda hatalar oluşabilir. Bu sorunu önlemek için aşağıdaki adımları uygulayın:

  1. PAGE_SIZE sabitine 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() veya sysconf(_SC_PAGESIZE) kullanın.

  2. 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 PAGE_SIZE değerini temel sayfa boyutuyla ilişkili olmayan uygun bir değer olarak kullanıyorsa bu durum, 16 KB modunda kullanıldığında uygulamanızın bozulmasına neden olmaz. Ancak bu değer MAP_FIXED olmadan mmap ile çekirdeğe iletilirse çekirdek yine de tam bir sayfa kullanır ve bu da biraz bellek israfına yol açar. 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 ayırdığı en küçük fiziksel bellek birimi, 4 KB sistemlerdekinden dört kat daha büyüktür. Özel bir ayırıcı 4 KB varsayımlarına göre tasarlanmışsa küçük nesneleri birden fazla 16 KB 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. Belleği boşaltmak için sabit kodlanmış bayt eşiklerinden 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, yayın eşiği hiçbir zaman karşılanmaz ve ayırıcı, çevreleyen kullanılmayan belleği asla çekirdeğe geri 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, gerçek sayfa boyutuna göre çalışma zamanında yayınlama eşiklerini dinamik olarak ölçeklendirin.

2. Önce halihazırda kullanılan sayfaları doldurma (yoğun öncelikli tahsis)

Bir ayırıcı, belleği ilk gelen ilk hizmet alır (FIFO) veya round-robin sırasına göre dağıtırsa yeni ayırmalar, kısmen dolu olan birçok 16 KB'lık sayfaya dağılır. Bir sayfadaki tek bir nesne, 16 KB'ın tamamının fiziksel RAM'de kalmasını sağlar.

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 tasarlanan çok sayfalı aralıklar, 16 KB çekirdeklerde aşırı miktarda yayınlanmamış bellek boşluğu tutabilir. 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'ler tahsis etmemek için küçük nesne sınıflarına yönelik ç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, genellikle büyük arabellekleri (> 64 KB) bellek içi havuzda önbelleğe alır. Böylece mmap veya munmap sistem çağrılarının ek yükü ödenmeden yeniden kullanılabilirler. Ancak bu kirli arabellekleri bellekte tutmak, çıkarma zamanlayıcısını beklerken megabaytlarca fiziksel RAM'i boşa harcar.

Ne yapmalısınız? Sanal bellek adresi aralığını hızlı yeniden kullanım için ayrılmış durumda tutun ancak 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 bellek ayırma yerine boşta olan 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 kalır veya ZRAM'e taşınır. Söz konusu 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 sırasında (free()) 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 durumları önlenir.

Ö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ı Önce en yoğun (neredeyse dolu) sayfadan veya bloktan ayırın. 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 göre ayarlayın ve çok büyük bloklardan kaçının. Kuyruk sayfası parçalanmasını ortadan kaldırır ve bellek boşluğunu azaltır.
Arabellek önbellekleri Büyük arabellekler önbelleğe alınırken madvise(MADV_DONTNEED) hemen çağrılır. Hızlı sanal yeniden kullanımı korurken boşta kalan RAM şişmesini ortadan kaldırır.
Takas / ZRAM Belleği ayırma sırasında değil, free() sırasında sıfırlayın. Sabitlenmiş sayfaların daha az maliyetli olması için ZRAM sıkıştırma oranlarını iyileştirir.

SDK'ların 16 KB desteğini kontrol etme

Birçok SDK, özellikle kendiniz oluşturursanız veya son önceden derlenmiş sürümleri alı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 etme

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:

  1. Android 15 SDK veya sonraki bir sürümü ayarlayın.

  2. Aşağıdaki test ortamlarından birini ayarlayın:

  3. 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_SIZE
    

    Komut, 16384 değerini döndürmelidir.

  4. Uygulamanızın 16 KB uyumlu olduğunu doğrulamak için aşağıdaki zipalign komutunu çalıştırın. Burada APK_NAME, uygulamanızın APK dosyasının adıdır:

    zipalign -c -P 16 -v 4 APK_NAME.apk
    
  5. Uygulamanızı kapsamlı bir şekilde test edin. Belirli sayfa boyutlarına referans veren kod örneklerinin değiştirilmesinden etkilenebilecek alanlara odaklanın.

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:

  1. Android Studio'da Tools > SDK Manager'ı (Araçlar > SDK Manager) tıklayın.
  2. SDK Platformları sekmesinde Paket Ayrıntılarını Göster'i seçin, ardından Android VanillaIceCream veya sonraki sürümler 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 ya da ikisini seçin:

    • Google API'leri Deneysel 16 KB Sayfa Boyutu ARM 64 v8a Sistem Resmi
    • Google APIs Experimental 16 KB Page Size Intel x86_64 Atom System Image
    Android Studio'daki SDK Manager'ı kullanarak 16 KB emülatör sistem görüntülerini indirme
  3. Seçtiğiniz sistem görüntülerini indirmek için Uygula > Tamam'ı tıklayın.

  4. 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 önerilmeyen 16 KB'lık sistem görüntüsünü Diğer Görüntüler sekmesinde bulabilirsiniz.

    16 KB emülatör görüntüsünü Diğer Görüntüler sekmesinde bulabilirsiniz.

Emülatörü başlatma

Android Emulator ve sanal cihazların kurulumunu tamamladıktan sonra, hedef cihaz menüsünden veya komut satırından emülatörü 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ı

Sayfa boyutu uyumluluk modunda uyarı

16 KB geriye dönük uyumluluk seçeneği, cihaz 16 KB çekirdekle çalışırken kullanılabilir. Paket yöneticisi, aşağıdaki koşullar karşılandığında bir uygulamayı 16 KB geriye dönük uyumluluk modunda çalıştırır:

  • Uygulamada, LOAD segment hizalaması 4 KB olan ELF dosyaları (.so uzantı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, Uygulamayı sayfa boyutu uyumluluk moduyla çalıştır ayarını etkinleştirerek veya devre dışı bırakarak belirli bir uygulama için 16 KB geriye dönük uyumluluk modunu etkinleştirebilir ya da devre dışı bırakabilirsiniz. Bu ayar yalnızca cihaz 16 KB sayfa boyutuyla çalışırken görünür.

Sayfa boyutu uyumluluk modu ayarı

Sayfa boyutu uyumluluk modu ayarı

Cihazdaki her uygulamada 16 KB geriye dönük uyumluluğu zorunlu kılmak için:

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.