Obsługa rozmiaru stron 16 KB

W przeszłości Android obsługiwał jedynie strony o rozmiarze 4 KB, które obsługują zoptymalizowana wydajność pamięci systemowej dla średniej ilości pamięci Urządzenia z Androidem zwykle mają Począwszy od Androida 15, AOSP obsługuje urządzenia skonfigurowane pod kątem używania strony o rozmiarze 16 KB (16 KB). urządzenia). Jeśli aplikacja korzysta z jakichkolwiek bibliotek NDK, bezpośrednio lub pośrednio za pomocą pakietu SDK, musisz ponownie skompilować aplikację, na urządzeniach o rozmiarze 16 KB.

W miarę jak producenci tworzą urządzenia, na których jest coraz więcej pamięci fizycznej (RAM) wiele z tych urządzeń będzie miało rozmiar 16 KB, w celu optymalizacji wydajności urządzenia. Dodaję obsługa urządzeń o rozmiarze strony 16 KB umożliwia urządzeń i pomaga aplikacji czerpać korzyści z powiązanej wydajności wiele ulepszeń. Bez ponownej kompilacji aplikacje mogą nie działać na urządzeniach o rozmiarze 16 KB podczas produkcji w kolejnych wersjach Androida.

Aby pomóc Ci w obsłudze aplikacji, przygotowaliśmy wskazówki, jak sprawdzić, jeśli ma to wpływ na Twoją aplikację, jak stworzyć aplikację ponownie (w stosownych przypadkach) i jak przetestować ją środowisko o wielkości 16 KB z emulatorami (w tym Android 15). obrazów systemu dla emulatora Androida).

Korzyści i wzrost wydajności

Urządzenia skonfigurowane z użyciem stron o rozmiarze 16 KB zużywają średnio nieco więcej pamięci, ale zyskują też różne ulepszenia wydajności zarówno systemu, jak i aplikacji:

  • Krótszy czas uruchamiania aplikacji, gdy system jest pod presją pamięci: średnio o 3,16% krótszy, a w przypadku niektórych testowanych aplikacji o znacznie więcej (do 30%).
  • Zmniejszone zużycie energii podczas uruchamiania aplikacji: średnio o 4,56%
  • Szybsze uruchamianie aparatu: średnio o 4,48% szybsze uruchomienia z pamięci i o 6,60% szybsze uruchomienia „na zimno”
  • Skrócony czas uruchamiania systemu: skrócenie o 8% (około 950 milisekund)

Te ulepszenia bazują na naszych wstępnych testach. Wyniki na rzeczywistych urządzeniach mogą się różnić. W miarę kontynuowania testów będziemy przeprowadzać dodatkową analizę potencjalnych zysków w przypadku aplikacji.

Sprawdź, czy zmiana wpłynie na Twoją aplikację

Jeśli aplikacja korzysta z kodu natywnego, musisz ponownie ją skompilować, aby obsługiwała urządzenia o pojemności 16 KB. Jeśli nie masz pewności, czy Twoja aplikacja używa kodu natywnego, użyj narzędzia APK Analyzer, aby sprawdzić, czy jest on obecny, a potem sprawdź wyrównanie segmentów ELF dla wszystkich znalezionych bibliotek współdzielonych.

Jeśli Twoja aplikacja używa tylko kodu napisanego w języku programowania Java lub Kotlin (w tym wszystkich bibliotekach i pakietach SDK), to jest już obsługiwana na urządzeniach o pojemności 16 KB. Zalecamy jednak przetestowanie aplikacji w środowisku 16 KB, aby sprawdzić, czy nie występują nieoczekiwane regresje w zachowaniu aplikacji.

Czy Twoja aplikacja korzysta z kodu natywnego?

Aplikacja używa kodu natywnego, jeśli spełnia co najmniej 1 z tych warunków:

  • Aplikacja używa kodu C/C++ (natywnego). Jeśli aplikacja korzysta z NDK Androida, używa kodu natywnego.
  • Twoja aplikacja zawiera linki do natywnych bibliotek lub zależności innych firm (np. pakietów SDK), które ich używają.
  • Twoja aplikacja została utworzona przez zewnętrznego kreatora aplikacji, który używa na urządzeniu bibliotek natywnych.

Identyfikowanie bibliotek natywnych za pomocą narzędzia APK Analyzer

APK Analyzer to narzędzie, które pozwala oceniać różne aspekty utworzonego pliku APK. Aby sprawdzić, czy Twoja aplikacja korzysta z kodu natywnego czy z bibliotek, wykonaj te czynności:

  1. Otwórz Android Studio, a następnie kliknij Plik > Otwórz i wybierz dowolny projekt.
  2. Na pasku menu kliknij Kompiluj > Przeanalizuj APK….

    Opcja w menu Kompilacja w Studio, która umożliwia uruchomienie narzędzia APK Analyzer

  3. Wybierz plik APK, który chcesz przeanalizować.

  4. Sprawdź folder lib, w którym przechowywane są pliki obiektów udostępnionych (.so), jeśli takie istnieją. Jeśli występują jakiekolwiek pliki obiektów współdzielonych, aplikacja używa kodu natywnego. Jeśli nie ma plików obiektów współdzielonych lub folderu lib, aplikacja nie używa kodu natywnego.

    Widok w APK Analyzer pokazujący, że pliki obiektów udostępnionych są obecne

Sprawdzanie wyrównania segmentów ELF w przypadku bibliotek współdzielonych

W przypadku wszystkich bibliotek udostępnionych sprawdź, czy ich segmenty ELF są prawidłowo wyrównane za pomocą wyrównania ELF 16 KB. Jeśli pracujesz na systemie Linux lub macOS, możesz użyć skryptu check_elf_alignment.sh zgodnie z opisem w następnej sekcji. Możesz też używać narzędzi wiersza poleceń bezpośrednio.

Użyj skryptu check_elf_alignment.sh (Linux lub macOS)

Aby sprawdzić wyrównanie segmentów ELF za pomocą skryptu check_elf_alignment.sh:

  1. Zapisz skrypt check_elf_alignment.sh w pliku.

  2. Uruchom skrypt na pliku APK aplikacji:

    check_elf_alignment.sh APK_NAME.apk
    

    Skrypt zwraca wartość ALIGNED lub UNALIGNED dla wszystkich arm64-v8azasobów wspólnych.

  3. Jeśli jakiekolwiek biblioteki współdzielone arm64-v8a lub x86_64 mają wartość UNALIGNED, musisz zaktualizować pakiety tych bibliotek, a następnie skompilować ponownie aplikację i ponownie ją przetestować, wykonując czynności opisane w tej sekcji.

Bezpośrednie korzystanie z narzędzi wiersza poleceń

Aby sprawdzić wyrównanie segmentów ELF bezpośrednio za pomocą narzędzi wiersza poleceń:

  1. Upewnij się, że pakiet Android SDK Build-Tools w wersji 35.0.0 lub nowszej oraz pakiet Android NDK są zainstalowane za pomocą Menedżera pakietu SDK w Android Studio lub narzędzia wiersza poleceń sdkmanager.
  2. Wyodrębnij plik APK aplikacji:

    Linux lub macOS

    unzip APK_NAME.apk -d /tmp/my_apk_out
    

    Windows (PowerShell)

    Expand-Archive -Path .\APK_NAME.apk -DestinationPath ~\tmp\my_apk_out
    
  3. W katalogu tymczasowym, do którego wyodrębniono plik APK, sprawdź zawartość katalogu lib pod kątem plików obiektów udostępnionych (.so). Są to te same pliki obiektów współdzielonych, które widzisz podczas identyfikowania bibliotek natywnych za pomocą narzędzia APK Analyzer. W przypadku każdego pliku obiektu współdzielonego uruchom to polecenie:

    Linux lub 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"
    

    gdzie SDK_ROOT_LOCATION to ścieżka do katalogu, w którym zainstalowano pakiet SDK Androida, SHARED_OBJECT_FILE to nazwa sprawdzanego pliku obiektu udostępnianego, a NDK_VERSION to wersja zainstalowanego NDK Androida (np. 28.0.12433566). Wyjście w przypadku każdego sprawdzanego pliku będzie wyglądać mniej więcej tak:

    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. Sprawdź wiersze danych, aby się upewnić, że segmenty ładowania nie mają wartości niższych niż 2**14. Jeśli dowolny segment wczytywania ma wartość 2**13, 2**12 lub niższą, musisz zaktualizować pakowanie tych bibliotek, a następnie skompilować aplikację i ponownie ją przetestować, wykonując czynności opisane w tej sekcji.

  5. Następnie uruchom narzędzie wiersza poleceń zipalign na pliku APK aplikacji:

    Linux lub 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
    

    Gdzie SDK_ROOT_LOCATION to ścieżka do katalogu, w którym zainstalowano pakiet SDK Androida, a APK_NAME to nazwa pliku APK aplikacji. Jeśli wszystkie współdzielone biblioteki są prawidłowo dopasowane, ostatni wiersz danych wyjściowych będzie zawierać komunikat „Verification successful” (Weryfikacja zakończona pomyślnie).

    Jeśli weryfikacja się nie powiedzie, niektóre biblioteki współdzielone trzeba będzie ponownie dostosować. W tym celu zaktualizuj pakowanie tych bibliotek, a następnie skompiluj ponownie aplikację i przeprowadź ponowny test, wykonując czynności opisane w tej sekcji.

Kompilowanie aplikacji z uwzględnieniem urządzeń z 16 KB

Aby obsługiwać urządzenia o rozmiary 16 KB, aplikacje korzystające z kodu natywnego powinny wykonać czynności opisane w następnych sekcjach. Jeśli zaktualizujesz AGP do wersji 8.5.1 lub nowszej i NDK do wersji r28 lub nowszej oraz używasz wstępnie skompilowanych zależności zgodnych z 16 KB, aplikacje będą domyślnie zgodne z 16 KB.

Zaktualizuj pakowanie swoich wspólnych bibliotek

Zalecamy przejście na AGP w wersji 8.5.1 lub nowszej i używanie niezdętych wspólnych bibliotek.

AGP w wersji 8.5.1 lub nowszej

Aplikacje na urządzeniach z 16 KB wymagają, aby biblioteki współużytkowane dostarczane w nieskompresowanej formie były dopasowane do granicy 16 KB. Aby to zrobić, musisz uaktualizować wtyczkę Android Gradle (AGP) do wersji 8.5.1 lub nowszej. Szczegółowe informacje o procesie uaktualnienia znajdziesz w sekcji Android Pomóż w uaktualnieniu wtyczki Gradle.

AGP w wersji 8.5 lub starszej.

Jeśli nie możesz uaktualnić AGP do wersji 8.5.1 lub nowszej, możesz zamiast tego użyć skompresowanych bibliotek wspólnych. Zaktualizuj konfigurację Gradle, aby Gradle kompresował biblioteki współdzielone podczas pakowania aplikacji. Pozwoli to uniknąć problemów z instalacją aplikacji z niezsynchronizowanymi bibliotekami współdzielonymi.

Groovy

W pliku build.gradle dodaj tę opcję:

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

Kotlin

W pliku build.gradle.kts dodaj tę opcję:

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

Kompilowanie aplikacji przy użyciu wyrównania ELF 16 KB

Aby aplikacja mogła działać na urządzeniach z 16 KB pamięci, segmenty ELF w bibliotekach wspólnych muszą być odpowiednio dopasowane za pomocą dopasowania ELF 16 KB.

Aby skompilować aplikację z wyrównaniem ELF 16 KB, wykonaj czynności opisane w jednej z poniższych sekcji, zależnie od wersji Android NDK, której używasz.

Android NDK r28 lub nowszy

NDK w wersji r28 i nowszych kompiluje domyślnie kod z wyrównaniem do 16 KB.

Android NDK r27

Aby umożliwić kompilowanie bibliotek współdzielonych dopasowanych do 16 KB za pomocą Android NDK w wersji r27 lub nowszej, musisz zaktualizować flagi ndk-build, build.gradle, build.gradle.kts lub linkera w ten sposób:

ndk-build

Na stronie Application.mk:

APP_SUPPORT_FLEXIBLE_PAGE_SIZES := true

Groovy

W pliku build.gradle ustaw argument -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

W pliku build.gradle.kts ustaw argument -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")
      }
    }
  }
}

Inne systemy kompilacji

Określ te flagi linkera:

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

Android NDK r26 i starsze

Aby umożliwić kompilowanie współdzielonych bibliotek z wyrównaniem do 16 KB za pomocą Android NDK w wersji r26 lub niższej, musisz zaktualizować konfigurację ndk-build lub cmake w ten sposób:

ndk-build

Zaktualizuj Android.mk, aby włączyć wyrównanie ELF 16 KB:

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

CMake

Zaktualizuj CMakeLists.txt, aby włączyć wyrównanie ELF 16 KB:

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

Sprawdź, czy istnieją fragmenty kodu, które odwołują się do określonych rozmiarów strony

Nawet jeśli aplikacja jest zgodna z rozmiarem 16 KB, może wyświetlać błędy, jeśli miejsca w kodzie zakładają, że urządzenie używa określonego rozmiaru strony. Aby tego uniknąć:

  1. Usuń zakodowane na stałe zależności, które odwołują się do stałej PAGE_SIZE lub jej wystąpień w logice kodu, które zakładają, że rozmiar strony na urządzeniu to 4 KB (4096).

    Zamiast tego użyj kolumny getpagesize() lub sysconf(_SC_PAGESIZE).

  2. Poszukaj wywołań funkcji mmap() i innych interfejsów API, które wymagają argumentów wyrównanych do strony, i w razie potrzeby zastąp je alternatywnymi funkcjami.

W niektórych przypadkach, jeśli Twoja aplikacja używa wartości PAGE_SIZE, która nie jest powiązana z podstawowym rozmiarem strony, nie spowoduje to jej uszkodzenia podczas korzystania z trybu 16 KB. Jeśli jednak ta wartość zostanie przekazana do jądra z wartością mmap bez MAP_FIXED, jądro nadal będzie używać całej strony, co spowoduje marnowanie pamięci. Z tych powodów wartość PAGE_SIZE jest niezdefiniowana, gdy tryb 16 KB jest włączony w NDK r27 lub nowszej wersji.

Jeśli Twoja aplikacja używa zmiennej PAGE_SIZE w ten sposób i nigdy nie przekazuje tej wartości bezpośrednio do jądra, zamiast PAGE_SIZE utwórz nową zmienną z nowym nazwą, aby odzwierciedlała ona inne przeznaczenie i nie odzwierciedlała rzeczywistej strony pamięci.

Sprawdzanie pakietów SDK pod kątem obsługi 16 KB

Wiele pakietów SDK jest zgodnych z rozmiarami stron 16 KB, zwłaszcza jeśli skompilujesz je samodzielnie lub użyjesz najnowszych wersji. Niektóre wstępnie utworzone pakiety SDK lub ich wersje nie są jednak zgodne z 16 KB, dlatego sprawdź na stronie każdego dostawcy pakietu SDK, której wersji użyć w przypadku 16 KB.

Testowanie aplikacji w środowisku o rozmiary 16 KB

Po skompilowaniu aplikacji z obsługą urządzeń o rozmiary 16 KB warto przetestować ją w takim środowisku, aby sprawdzić, czy nie występują w niej regresje. W tym celu należy wykonać następujące czynności:

  1. Skonfiguruj pakiet SDK Androida 15

  2. Skonfiguruj jedno z tych środowisk testowych:

  3. Uruchom urządzenie testowe, a potem uruchom to polecenie, aby sprawdzić, czy używa ono środowiska o rozmaju 16 KB:

    adb shell getconf PAGE_SIZE
    

    Polecenie powinno zwrócić wartość 16384.

  4. Aby sprawdzić, czy aplikacja jest wyrównana co 16 KB, uruchom to polecenie zipalign, gdzie APK_NAME to nazwa pliku APK aplikacji:

    zipalign -c -P 16 -v 4 APK_NAME.apk
    
  5. Dokładnie przetestuj aplikację, zwracając uwagę na obszary, na które może mieć wpływ zmian kodów odwołujących się do określonych rozmiarów stron.

Konfigurowanie emulatora Androida za pomocą obrazu systemu Android 15 opartym na 16 KB

Aby skonfigurować środowisko 16 KB za pomocą emulatora Androida, wykonaj te czynności:

  1. Obrazy systemowe emulatora Androida 15 o rozmiary 16 KB są zgodne z Android Studio Jellyfish | 2023.3.1 lub nowszym. Aby jednak uzyskać najlepsze wrażenia podczas pracy z Androidem 15 w wersji beta, pobierz najnowszą wersję podglądową Android Studio.

    Pamiętaj, że możesz zachować dotychczasową wersję Android Studio, ponieważ możesz zainstalować wiele wersji naraz.

  2. W Android Studio kliknij Narzędzia > Menedżer pakietu SDK.

  3. Na karcie Platformy pakietu SDK zaznacz pole Pokaż szczegóły pakietu, a potem rozwiń sekcję Android VanillaIceCream Preview i wybierz jeden lub oba te obrazy systemu emulatora, w zależności od tego, jakie urządzenia wirtualne chcesz utworzyć:

    • Interfejsy API Google Eksperymentalny obraz systemowy ARM 64 v8a o rozmiarze strony 16 kB
    • Interfejsy Google API – eksperymentalny obraz systemu Intel x86_64 Atom o rozmiarze strony 16 kB

    Pobieranie obrazów systemu emulatora o rozmiary 16 KB za pomocą Menedżera pakietu SDK w Android Studio

  4. Aby pobrać wybrane obrazy systemu, kliknij Zastosuj > OK.

  5. Wykonaj czynności konfigurowania urządzenia wirtualnego dla Androida 15, a gdy pojawi się prośba o wybranie obrazu systemu, wybierz pobrany obraz systemu o rozmiary 16 KB. Jeśli nie jest zalecane automatyczne tworzenie, obraz systemu o rozmiary 16 KB znajdziesz na karcie Inne obrazy.

    Znajdź obraz emulatora 16 KB na karcie Inne obrazy

  1. W Menedżerze urządzeń kliknij 3 kropki obok obrazu o rozmiarze 16 KB, a następnie kliknij Pokaż na dysku.
  2. W tym folderze znajdź plik config.ini.
  3. Dodaj ten wiersz do pliku config.ini i zapisz zmiany:

    kernel.parameters = androidboot.page_shift=14
    
  4. Aby sprawdzić zmiany, uruchom to polecenie, które powinno zwrócić wartość 16384:

    adb shell getconf PAGE_SIZE
    

Włączanie trybu 16 KB na urządzeniu za pomocą opcji programisty

Przełącz opcję Uruchom ze stroną 16 KB, aby uruchomić urządzenie w trybie 16 KB.

Od Androida 15 QPR1 możesz korzystać z opcji dla deweloperów, która jest dostępna na niektórych urządzeniach, aby uruchomić urządzenie w trybie 16 KB i przeprowadzić testy na urządzeniu.

Ta opcja dla deweloperów jest dostępna na tych urządzeniach:

  • Pixel 8 i Pixel 8 Pro (z Androidem 15 QPR1 lub nowszym)
  • Pixel 8a (z Androidem 15 QPR1 lub nowszym)
  • Pixel 9, 9 Pro i 9 Pro XL (z Androidem 15 QPR2 Beta 2 lub nowszym)