תמיכה בגודלי דפים של 16KB

Historically, Android has only supported 4 KB memory page sizes, which has optimized system memory performance for the average amount of total memory that Android devices have typically had. Beginning with Android 15, AOSP supports devices that are configured to use a page size of 16 KB (16 KB devices). If your app uses any NDK libraries, either directly or indirectly through an SDK, then you will need to rebuild your app for it to work on these 16 KB devices.

As device manufacturers continue to build devices with larger amounts of physical memory (RAM), many of these devices will adopt 16 KB (and eventually greater) page sizes to optimize the device's performance. Adding support for 16 KB page size devices enables your app to run on these devices and helps your app benefit from the associated performance improvements. Without recompiling, apps might not work on 16 KB devices when they are productionized in future Android releases.

To help you add support for your app, we've provided guidance on how to check if your app is impacted, how to rebuild your app (if applicable), and how to test your app in a 16 KB environment using emulators (including Android 15 system images for the Android Emulator).

יתרונות ושיפורים בביצועים

Devices configured with 16 KB page sizes use slightly more memory on average, but also gain various performance improvements for both the system and apps:

  • Lower app launch times while the system is under memory pressure: 3.16% lower on average, with more significant improvements (up to 30%) for some apps that we tested
  • Reduced power draw during app launch: 4.56% reduction on average
  • Faster camera launch: 4.48% faster hot starts on average, and 6.60% faster cold starts on average
  • Improved system boot time: improved by 1.5% (approximately 0.8 seconds) on average

These improvements are based on our initial testing, and results on actual devices will likely differ. We'll provide additional analysis of potential gains for apps as we continue our testing.

איך בודקים אם האפליקציה מושפעת?

If your app uses any native code, then you should rebuild your app with support for 16 KB devices. If you are unsure if your app uses native code, you can use the APK Analyzer to identify whether any native code is present.

If your app only uses code written in the Java programming language or in Kotlin, including all libraries or SDKs, then your app already supports 16 KB devices. Nevertheless, we recommend that you test your app in a 16 KB environment to verify that there are no unexpected regressions in app behavior.

האם האפליקציה שלך משתמשת בקוד נייטיב?

האפליקציה שלך משתמשת בקוד נייטיב אם אחד מהמצבים הבאים רלוונטי:

  • האפליקציה שלך משתמשת בכל קוד C/C++ (מותאם). אם האפליקציה משתמשת בAndroid NDK, ואז האפליקציה תשתמש בקוד נייטיב.
  • האפליקציה שלך מקשרת לספריות מותאמות או ליחסי תלות של צד שלישי להשתמש בהם.
  • האפליקציה שלך נוצרה על ידי כלי של צד שלישי ליצירת אפליקציות שמשתמש בספריות מקוריות במכשיר.

זיהוי ספריות מקוריות באמצעות כלי הניתוח של APK

כלי הניתוח ל-APK הוא כלי שמאפשר לכם להעריך היבטים שונים של APK כדי לבדוק אם האפליקציה שלך משתמשת בקוד מקורי או בספריות, יש לפעול לפי שלבים:

  1. פותחים את Android Studio ולוחצים על קובץ > פותחים את האפליקציה ובוחרים פרויקט כלשהו.
  2. בסרגל התפריטים, לוחצים על Build > (פיתוח >) ניתוח APK...

    אפשרות התפריט להפעלת APK ב-Studio Build
מכשיר לניתוח פעולות

  3. בוחרים את ה-APK שרוצים לנתח.

  4. בודקים בתוך התיקייה lib, שמארחת קבצים של אובייקטים משותפים (.so), אם יש כאלה קיימים. אם קיימים קובצי אובייקטים משותפים, האפליקציה משתמשת ב-Native אם לא קיימים קובצי אובייקטים משותפים או שאין תיקיית lib, אז האפליקציה שלך לא משתמשת בקוד נייטיב.

    תצוגה של כלי הניתוח APK שמראה שקובצי אובייקטים משותפים
כיום

בניית האפליקציה עם תמיכה במכשירים עם 16KB

כדי לתמוך במכשירים עם 16KB, אפליקציות שמשתמשות בקוד נייטיב צריכות להשלים את התהליך השלבים המפורטים בקטעים הבאים.

עדכון החבילה של הספריות המשותפות

מומלץ לשדרג ל-AGP לגרסה 8.3 ואילך ולהשתמש במצב לא דחוס של ספריות משותפות.

AGP גרסה 8.3 ואילך

במכשירים עם 16 KB נדרשים אפליקציות שנשלחות עם ספריות משותפות לא דחוסות כדי ליישר אותם על גבול מיושר בגודל 16KB. כדי לעשות את זה, צריך לשדרג ל-Android Gradle Plugin (AGP) בגרסה 8.3 ואילך. ראה Android לפרטים על תהליך השדרוג, הקטע 'עוזר דיגיטלי לשדרוג הפלאגין של Gradle'.

AGP גרסה 8.2 ומטה

אם אין לך אפשרות לשדרג את AGP לגרסה 8.3 ואילך, האפשרות עוברים להשתמש בספריות משותפות דחוסות. עדכון ההגדרות האישיות של Gradle ל לדחוס את הספריות המשותפות במהלך האריזה של האפליקציה כדי למנוע שימוש ב-Gradle בהתקנה של ספריות משותפות לא תואמות.

Groovy

בקובץ build.gradle, מוסיפים את האפשרות הבאה:

android {
  ...
  packagingOptions {
      jniLibs {
        useLegacyPackaging true
      }
  }
}

Kotlin

בקובץ build.gradle.kts, מוסיפים את האפשרות הבאה:

android {
  ...
  packagingOptions {
      jniLibs {
        useLegacyPackaging = true
      }
  }
}

הידור האפליקציה באמצעות יישור ELF של 16KB

למכשירים עם 16KB נדרשת הספריות המשותפות מקטעי ELF ליישור באמצעות התאמת ELF של 16KB כדי שהאפליקציה תפעל.

כדי להדר את האפליקציה באמצעות התאמת ELF של 16KB, מבצעים את השלבים באחד בקטעים הבאים, בהתאם לגרסת Android NDK שיש לך באמצעות.

Android NDK r26 ומטה

כדי לתמוך בהידור של ספריות משותפות שמותאמות ל-16KB עם Android NDK מגרסה 26 ומטה, צריך לעדכן את ndk-build או cmake את התצורה שלו באופן הבא:

ndk-build

מעדכנים את Android.mk כדי להפעיל התאמה של ELF בנפח 16KB:

LOCAL_LDFLAGS += "-Wl,-z,max-page-size=16384"

CMake

מעדכנים את CMakeLists.txt כדי להפעיל התאמה של ELF בנפח 16KB:

target_link_options(${CMAKE_PROJECT_NAME} PRIVATE "-Wl,-z,max-page-size=16384")

Android NDK r27 ואילך

כדי לתמוך בהידור של ספריות משותפות שמותאמות ל-16KB עם Android NDK מגרסה r27 ואילך, עליך לעדכן את ndk-build, build.gradle, build.gradle.kts, או מגדיר קישורים באופן הבא:

ndk-build

בתוך Application.mk:

APP_SUPPORT_FLEXIBLE_PAGE_SIZES := true

Groovy

בקובץ build.gradle, מגדירים את הארגומנט -DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON:

android {
  ...
  defaultConfig {
    ...
    // This block is different from the one you use to link Gradle
    // to your CMake or ndk-build script.
    externalNativeBuild {
      // For ndk-build, instead use the ndkBuild block.
      cmake {
        // Passes optional arguments to CMake.
        arguments "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
      }
    }
  }
}

Kotlin

בקובץ build.gradle.kts, מגדירים את הארגומנט -DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON:

android {
  ...
  defaultConfig {
    ...
    // This block is different from the one you use to link Gradle
    // to your CMake or ndk-build script.
    externalNativeBuild {
      // For ndk-build, instead use the ndkBuild block.
      cmake {
        // Passes optional arguments to CMake.
        arguments += listOf("-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON")
      }
    }
  }
}

מערכות פיתוח אחרות

מציינים את דגלי ה-linker הבאים:

-Wl,-z,max-page-size=16384

חיפוש מופעי קוד שמפנים לגדלים ספציפיים של דפים

גם אם האפליקציה מותאמת ל-16KB, האפליקציה עשויה להיתקל בשגיאות אם מקומות בקוד שלך, נניח שמכשיר משתמש בגודל דף מסוים. כדי להימנע מכך, מבצעים את השלבים הבאים:

  1. מסירים יחסי תלות בתוך הקוד שמפנה אל PAGE_SIZE קבועים או מופעים בלוגיקת הקוד שלכם שמניחים כי דף המכשיר הגודל הוא 4KB (4096).

    במקומו צריך להשתמש ב-getpagesize() או ב-sysconf(_SC_PAGESIZE).

  2. חיפוש שימושים ב-mmap() ובממשקי API אחרים שמחייבים יישור דף ארגומנטים ולהחליף אותם בחלופות במקרה הצורך.

במקרים מסוימים, אם האפליקציה משתמשת ב-PAGE_SIZE כערך נוח שאינו שמקושר לגודל הדף הבסיסי, זה לא יגרום לאפליקציה לקרוס בשימוש במצב 16KB. אבל אם הערך הזה מועבר לליבה, עם mmap בלי MAP_FIXED, הליבה עדיין משתמשת בדף שלם, זה מבזבז חלק מהזיכרון. מהסיבות האלה, PAGE_SIZE לא מוגדר כאשר 16KB מופעל ב-NDK r27 ואילך.

אם האפליקציה משתמשת ב-PAGE_SIZE באופן הזה ואף פעם לא מעבירה את הערך הזה ישירות אל בליבה, ובמקום להשתמש ב-PAGE_SIZE, יוצרים משתנה חדש עם כדי לשקף שהוא משמש למטרות אחרות ואינו משקף דף הזיכרון.

בדיקת האפליקציה בסביבה של 16KB

אחרי שיוצרים את האפליקציה עם תמיכה במכשירים בגודל 16KB, צריך לבדוק את האפליקציה בסביבה של 16KB כדי לראות אם חוויית השימוש באפליקציה רגרסיות כלשהן. לשם כך, בצע את הצעדים הבאים:

  1. כך מגדירים את Android 15 SDK.

  2. מגדירים את אחת מסביבות הבדיקה הבאות:

  3. מפעילים את מכשיר הבדיקה ואז מריצים את הפקודה הבאה כדי לוודא הוא משתמש בסביבה של 16KB:

    adb shell getconf PAGE_SIZE
    

    הפקודה צריכה להחזיר את הערך 16384.

  4. אם יש ספריות משותפות, עליך לוודא שהספריות המשותפות הפלחים של ELF מיושרים כראוי באמצעות יישור ELF של 16KB. אפשר להשתמש בסקריפט הזה כדי עזרה בתהליך הזה:

    #!/bin/bash
    
    # usage: alignment.sh path to search for *.so files
    
    dir="$1"
    
    RED="\e[31m"
    GREEN="\e[32m"
    ENDCOLOR="\e[0m"
    
    matches="$(find $dir -name "*.so" -type f)"
    IFS=$'\n'
    for match in $matches; do
      res="$(objdump -p ${match} | grep LOAD | awk '{ print $NF }' | head -1)"
      if [[ $res =~ "2**14" ]] || [[ $res =~ "2**16" ]]; then
        echo -e "${match}: ${GREEN}ALIGNED${ENDCOLOR} ($res)"
      else
        echo -e "${match}: ${RED}UNALIGNED${ENDCOLOR} ($res)"
      fi
    done
    
    1. שומרים את הסקריפט בקובץ, כמו alignment.sh.

    2. חלץ את קובץ ה-APK של האפליקציה:

      unzip APK_NAME.apk -d /tmp/my_apk_out
      
    3. מריצים את הסקריפט בקבצים שחולצו דרך /tmp/my_apk_out ספרייה:

      alignment.sh /tmp/my_apk_out | grep "arm64-v8a"
      

      הפלט של הסקריפט הוא ALIGNED או UNALIGNED עבור כל arm64-v8a ספריות משותפות.

    4. אם יש arm64-v8a ספריות משותפות שUNALIGNED, עליך לעדכן את האריזה של הספריות האלה, ואז להרכיב מחדש את ובודקים מחדש את האפליקציה לפי השלבים שמפורטים בקטע הזה.

  5. מריצים את הפקודה הבאה zipalign כדי לאמת שהאפליקציה יישור ל-16KB, כאשר APK_NAME הוא השם של קובץ ה-APK של האפליקציה:

    zipalign -c -P 16 -v 4 APK_NAME.apk
    
  6. בודקים ביסודיות את האפליקציה ומתמקדים בתחומים שעשויים להיות מושפעים ממנה שינוי מופעי קוד שמציינים גדלים ספציפיים של דפים

הגדרת אמולטור Android עם תמונת מערכת של Android 15 שמבוססת על 16KB

כדי להגדיר סביבה של 16KB באמצעות האמולטור Android, פועלים לפי השלבים הבאים שלבים:

  1. תמונות של מערכת אמולטור Android 15 שמבוססות על 16KB תואמות מדוזה ב-Android Studio | 2023.3.1 ואילך. אבל כדי לשפר את בעבודה עם גרסת Android 15 בטא, הורידו את הגרסה גרסת טרום-השקה (Preview) של Android Studio.

    חשוב לזכור שאפשר להמשיך להשתמש בגרסה הקיימת של Android Studio מותקנת, כי ניתן להתקין כמה גרסאות זו לצד זו.

  2. ב-Android Studio, לוחצים על כלים > SDK Manager.

  3. בכרטיסייה SDK Platforms (פלטפורמות SDK), מסמנים את האפשרות Show Package Details (הצגת פרטי החבילה) ומרחיבים אותה. בקטע Android VanillaIceCream Preview ובוחרים באחת מהאפשרויות האלה או בשניהם את התמונות הבאות של מערכת האמולטור, בהתאם למכשירים הווירטואליים שרוצים ליצור:

    • תמונת מערכת ניסיונית של Google APIs בגודל 16k של דף ARM 64 v8a
    • תמונת מערכת ניסיונית של Google APIs בגודל 16k של Intel x86_64

    הורדת תמונות מערכת של אמולטור בגודל 16KB באמצעות 'מנהל ה-SDK' ב-Android
סטודיו

  4. לוחצים על החלה > אישור כדי להוריד את תמונות המערכת שבחרתם.

  5. פועלים לפי השלבים להגדרת מכשיר וירטואלי ל-Android 15. כשתוצג בקשה לבחור תמונת מערכת, צריך לבחור את תמונת המערכת בגודל 16 KB שהורדתם. אם האפשרות לא מומלצת באופן אוטומטי, אפשר למצוא תמונת מערכת בגודל 16KB בכרטיסייה תמונות אחרות.

    חיפוש תמונת האמולטור בגודל 16KB ב'תמונות אחרות'
טאב

  1. במנהל המכשירים, לוחצים על סמל התפריט (3 נקודות) שלצד התמונה בגודל 16KB, ואז לוחצים על הצגה בדיסק.
  2. מאתרים את הקובץ config.ini בתיקייה הזו.
  3. מוסיפים את השורה הבאה לקובץ config.ini ושומרים את השינויים:

    kernel.parameters = androidboot.page_shift=14
    
  4. כדי לאמת את השינויים, מריצים את הפקודה הבאה, שאמורה לחזור 16384:

    adb shell getconf PAGE_SIZE