16 KB ページサイズのサポート

これまで、Android は 4 KB のメモリページサイズしかサポートしていませんでした。 システムメモリのパフォーマンスを最適化 Android デバイスでは通常、これが行われています。Android 15 以降、AOSP は 16 KB(16 KB)のページサイズを使用するように設定されているデバイス 。アプリで NDK ライブラリを直接使用している場合は、 または SDK を介して間接的に行う場合、アプリを再ビルドして 16 KB のデバイスで使用できます。

デバイス メーカーは次々と、より多くのデバイスで 物理メモリ(RAM)に加え、これらのデバイスの多くに 16 KB( ページサイズを拡大して、デバイスのパフォーマンスを最適化します。追加しています 16 KB ページサイズのデバイスをサポートしているため、アプリはこれらの 関連するパフォーマンスの恩恵をアプリに提供するため 改善されています。16 KB デバイスでは、再コンパイルしないとアプリが動作しない可能性があります 将来の Android リリースで製品化される際の要件です。

アプリのサポートを追加できるように、 アプリが影響を受ける場合はアプリを再構築し(該当する場合)、アプリをテスト エミュレータ(Android 15 を含む)を使用した 16 KB 環境 Android Emulator 用のシステム イメージ)を作成します。

メリットとパフォーマンスの向上

16 KB のページサイズで構成されたデバイスでは、平均でメモリ使用量が若干増加しますが、システムとアプリの両方でさまざまなパフォーマンスが向上します。

  • システムのメモリ負荷が高いときのアプリ起動時間の短縮: 平均 3.16% 短縮、テストした一部のアプリでは大幅な改善(最大 30%)
  • アプリ起動時の消費電力の削減: 平均 4.56% 削減
  • カメラの起動が速くなる: ホット スタートが平均 4.48%、コールド スタートが平均 6.60% 高速化
  • システムの起動時間の短縮: 平均で 8%(約 950 ミリ秒)短縮

これらの改善は初期テストに基づくものであり、実際のデバイスでの結果は異なる可能性があります。テストを継続する中で、アプリの潜在的な収益増加に関する追加の分析情報を提供していきます。

アプリが影響を受けるかどうかを確認する

アプリがネイティブ コードを使用している場合は、16 KB デバイスをサポートするようにアプリを再ビルドする必要があります。アプリがネイティブ コードを使用しているかどうか不明な場合は、APK アナライザを使用してネイティブ コードが存在するかどうかを特定し、検出された共有ライブラリの ELF セグメントの配置をチェックします。

ライブラリや SDK もすべて含めて、Java プログラミング言語または Kotlin で記述されたコードだけを使用しているアプリは、すでに 16 KB デバイスをサポートしています。ただし、16 KB 環境でアプリをテストし、アプリの動作に予期しないリグレッションがないことを確認することをおすすめします。

アプリがネイティブ コードを使用しているか?

次のいずれかに該当する場合は、アプリでネイティブ コードを使用しています。

  • アプリで C/C++(ネイティブ)コードを使用している。アプリで Android NDK を使用している場合は、アプリでネイティブ コードを使用しています。
  • アプリが、それらを使用するサードパーティのネイティブ ライブラリまたは依存関係(SDK など)とリンクしている。
  • アプリが、デバイス上のネイティブ ライブラリを使用するサードパーティ製アプリビルダーでビルドされている。

APK Analyzer を使用してネイティブ ライブラリを特定する

APK Analyzer は、ビルドされた APK のさまざまな要素を評価するためのツールです。アプリがネイティブ コードとライブラリのどちらを使用しているかを確認する手順は次のとおりです。

  1. Android Studio を開き、[File] > [Open] をクリックして任意のプロジェクトを選択します。
  2. メニューバーで、[Build] > [Analyze APK...] をクリックします。

    APK Analyzer を起動する Studio の [Build] メニュー オプション

  3. 分析する APK を選択します。

  4. lib フォルダ内を調べます。共有オブジェクト(.so)ファイルがある場合はここにホストされています。共有オブジェクト ファイルが存在する場合、アプリはネイティブ コードを使用しています。共有オブジェクト ファイルが存在しない場合や、lib フォルダが存在しない場合、アプリはネイティブ コードを使用していません。

    共有オブジェクト ファイルが存在することを示す APK Analyzer ビュー

共有ライブラリの ELF セグメントのアライメントを確認する

共有ライブラリについては、16 KB ELF アライメントを使用して、共有ライブラリの ELF セグメントが適切にアライメントされていることを確認します。Linux または macOS で開発している場合は、次のセクションで説明するように check_elf_alignment.sh スクリプトを使用できます。コマンドライン ツールを直接使用することもできます。

check_elf_alignment.sh スクリプトを使用する(Linux または macOS)

check_elf_alignment.sh スクリプトを使用して ELF セグメントの配置を確認する手順は次のとおりです。

  1. check_elf_alignment.sh スクリプトをファイルに保存します。

  2. アプリの APK ファイルでスクリプトを実行します。

    check_elf_alignment.sh APK_NAME.apk
    

    このスクリプトは、すべての arm64-v8a 共有ライブラリに対して ALIGNED または UNALIGNED を出力します。

  3. arm64-v8a または x86_64 共有ライブラリが UNALIGNED の場合は、これらのライブラリのパッケージを更新してから、アプリを再コンパイルし、このセクションの手順に沿って再テストする必要があります。

コマンドライン ツールを直接使用する

コマンドライン ツールを直接使用して ELF セグメントの配置を確認する手順は次のとおりです。

  1. Android Studio の SDK Manager または sdkmanager コマンドライン ツールを使用して、Android SDK Build-Tools バージョン 35.0.0 以降と Android NDK の両方がインストールされていることを確認します。
  2. アプリの APK ファイルを展開します。

    Linux または 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 ファイルを展開した一時ディレクトリで、lib ディレクトリの内容を確認して、共有オブジェクト(.so)ファイルがないか確認します。これは、APK Analyzer を使用してネイティブ ライブラリを特定する際に表示された共有オブジェクト ファイルと同じです。共有オブジェクト ファイルごとに次のコマンドを実行します。

    Linux または 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"
    

    ここで、SDK_ROOT_LOCATION は Android SDK をインストールしたディレクトリのパス、SHARED_OBJECT_FILE はチェックする共有オブジェクト ファイルの名前、NDK_VERSION はインストールした Android NDK のバージョン(28.0.12433566 など)です。出力は、チェックするファイルごとに次のような形式になります。

    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. 出力行を確認して、負荷セグメントの値が 2**14 未満でないことを確認します。読み込みセグメントが 2**132**12、またはそれより低い値の場合は、該当するライブラリのパッケージを更新してから、アプリを再コンパイルし、このセクションの手順に沿って再テストする必要があります。

  5. 次に、アプリの APK ファイルで zipalign コマンドライン ツールを実行します。

    Linux または 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
    

    ここで、SDK_ROOT_LOCATION は Android SDK をインストールしたディレクトリのパス、APK_NAME はアプリの APK ファイルの名前です。すべての共有ライブラリが正しく配置されている場合、出力の最後の行に「検証成功」と表示されます。

    検証に失敗した場合は、一部の共有ライブラリを再調整する必要があります。そのため、それらのライブラリのパッケージを更新してから、アプリを再コンパイルし、このセクションの手順に沿って再テストする必要があります。

16 KB デバイスをサポートするようにアプリをビルドする

16 KB デバイスをサポートするには、ネイティブ コードを使用するアプリで、以下のセクションで説明する手順を完了する必要があります。AGP バージョン 8.5.1 以降と NDK バージョン r28 以降にアップデートし、16 KB 互換のビルド済み依存関係を使用すると、アプリはデフォルトで 16 KB 互換になります。

共有ライブラリのパッケージを更新する

AGP バージョン 8.5.1 以降にアップグレードし、圧縮されていない共有ライブラリを使用することをおすすめします。

AGP バージョン 8.5.1 以降

16 KB デバイスでは、圧縮されていない共有ライブラリが付属するアプリを 16 KB の ZIP アライメント境界に配置する必要があります。これを行うには、Android Gradle プラグイン(AGP)バージョン 8.5.1 以降にアップグレードする必要があります。アップグレード プロセスの詳細については、Android Gradle プラグインの Upgrade Assistant セクションをご覧ください。

AGP バージョン 8.5 以前

AGP をバージョン 8.5.1 以降にアップグレードできない場合は、圧縮共有ライブラリの使用に切り替えることもできます。調整されていない共有ライブラリによるアプリのインストールに関する問題を回避するため、アプリをパッケージ化するときに Gradle が共有ライブラリを圧縮するように Gradle の構成を更新します。

Groovy

build.gradle ファイルに次のオプションを追加します。

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

Kotlin

build.gradle.kts ファイルに次のオプションを追加します。

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

16 KB ELF アライメントを使用してアプリをコンパイルする

16 KB デバイスでアプリを実行するには、共有ライブラリの ELF セグメントを 16 KB ELF アライメントを使用して適切にアライメントする必要があります。

16 KB ELF アライメントを使用してアプリをコンパイルするには、使用している Android NDK のバージョンに応じて、次のいずれかのセクションの手順を完了します。

Android NDK r28 以降

NDK バージョン r28 以降では、デフォルトで 16 KB アライメントでコンパイルされます。

Android NDK r27

Android NDK バージョン r27 以降で 16 KB アライメントの共有ライブラリのコンパイルをサポートするには、ndk-buildbuild.gradlebuild.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")
      }
    }
  }
}

他のビルドシステム

次のリンカーフラグを指定します。

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

Android NDK r26 以前

Android NDK バージョン r26 以前で 16 KB アライメントの共有ライブラリのコンパイルをサポートするには、次のように ndk-build または cmake の構成を更新する必要があります。

ndk-build

16 KB ELF アライメントを有効にするように Android.mk を更新します。

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

CMake

16 KB ELF アライメントを有効にするように CMakeLists.txt を更新します。

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

特定のページサイズを参照するコード インスタンスを確認する

アプリが 16 KB アライメントであっても、コード内の特定の場所がデバイスが特定のページサイズを使用していると想定している場合、アプリでエラーが発生する可能性があります。これを回避するには、次の手順を完了します。

  1. デバイスのページサイズが 4 KB(4096)であることを前提とするコードロジック内の PAGE_SIZE 定数またはインスタンスを参照するハードコードされた依存関係をすべて削除します。

    代わりに getpagesize() または sysconf(_SC_PAGESIZE) を使用してください。

  2. ページ境界に合わせた引数を必要とする mmap() などの API の使用箇所を探し、必要に応じて代替手段に置き換えます。

アプリで PAGE_SIZE を基盤となるページサイズに関連付けられていない便利な値として使用している場合、16 KB モードで使用してもアプリが破損することはありません。ただし、この値が MAP_FIXED なしで mmap でカーネルに渡されると、カーネルはページ全体を使用するため、メモリが浪費されます。このような理由から、NDK r27 以降で 16 KB モードが有効になっている場合、PAGE_SIZE は未定義になります。

アプリがこのように PAGE_SIZE を使用していて、この値をカーネルに直接渡さない場合は、PAGE_SIZE を使用する代わりに、新しい名前の新しい変数を作成して、他の目的で使用され、実際のメモリページを反映していないことを示します。

SDK で 16 KB のサポートを確認する

多くの SDK は 16 KB のページサイズに対応しています(特に、自分でビルドする場合や最新のビルド済みファイルを入手する場合)。ただし、一部の SDK ビルド済みまたは SDK バージョンは 16 KB に対応していないため、16 KB で使用するバージョンを判断するには、各 SDK プロバイダのウェブサイトを確認する必要があります。

16 KB 環境でアプリをテストする

16 KB デバイスをサポートするようにアプリをビルドしたら、16 KB 環境でアプリをテストして、アプリにリグレッションが発生していないか確認します。手順は次のとおりです。

  1. Android 15 SDK をセットアップする

  2. 次のいずれかのテスト環境を設定します。

  3. テストデバイスを起動して、次のコマンドを実行し、16 KB 環境を使用していることを確認します。

    adb shell getconf PAGE_SIZE
    

    このコマンドは 16384 の値を返します。

  4. 次の zipalign コマンドを実行して、アプリが 16 KB でアライメントされていることを確認します。ここで、APK_NAME はアプリの APK ファイルの名前です。

    zipalign -c -P 16 -v 4 APK_NAME.apk
    
  5. 特定のページサイズを参照するコード インスタンスの変更によって影響を受ける可能性がある領域に重点を置いて、アプリを徹底的にテストします。

16 KB ベースの Android 15 システム イメージを使用して Android Emulator を設定する

Android Emulator を使用して 16 KB 環境をセットアップする手順は次のとおりです。

  1. 16 KB ベースの Android 15 エミュレータ システム イメージは、Android Studio Jellyfish | 2023.3.1 以降と互換性があります。ただし、Android 15 ベータ版を利用する場合は、Android Studio の最新のプレビュー版をダウンロードすることをおすすめします。

    なお、Android Studio は複数のバージョンを一緒にインストールできるので、Android Studio の既存のバージョンをインストールしたままにしておくことができます。

  2. Android Studio で [Tools] > [SDK Manager] をクリックします。

  3. [SDK Platforms] タブで [Show Package Details] をオンにして、[Android VanillaIceCream Preview] セクションを開き、作成する仮想デバイスに応じて、次のいずれかまたは両方のエミュレータ システム イメージを選択します。

    • Google APIs 試験運用版 16 KB ページサイズ ARM 64 v8a システム イメージ
    • Google APIs 試験運用版 16k ページサイズ Intel x86_64 Atom システム イメージ

    Android Studio の SDK Manager を使用して 16 KB のエミュレータ システム イメージをダウンロードする

  4. [適用] > [OK] をクリックして、選択したシステム イメージをダウンロードします。

  5. 手順に沿って Android 15 の仮想デバイスをセットアップし、システム イメージを選択するよう求められたら、ダウンロードした 16 KB のシステム イメージを選択します。自動的に推奨されない場合は、[その他の画像] タブで 16 KB のシステム イメージを確認できます。

    [その他の画像] タブで 16 KB のエミュレータ イメージを見つけます。

  1. デバイス マネージャーで、16 KB の画像の横にある 3 つの点をクリックし、[ディスクに表示] をクリックします。
  2. このフォルダで config.ini ファイルを探します。
  3. config.ini ファイルに次の行を追加して、変更を保存します。

    kernel.parameters = androidboot.page_shift=14
    
  4. 変更を確認するには、次のコマンドを実行します。16384 が返されます。

    adb shell getconf PAGE_SIZE
    

開発者向けオプションを使用してデバイスで 16 KB モードを有効にする

[16 KB ページサイズで起動する] デベロッパー オプションを切り替えて、デバイスを 16 KB モードで起動します。

Android 15 QPR1 以降では、特定のデバイスで利用可能な開発者向けオプションを使用して、デバイスを 16 KB モードで起動し、デバイス上のテストを実行できます。

この開発者向けオプションは、次のデバイスで使用できます。

  • Google Pixel 8 と Google Pixel 8 Pro(Android 15 QPR1 以降)
  • Google Pixel 8a(Android 15 QPR1 以降)
  • Google Pixel 9、Google Pixel 9 Pro、Google Pixel 9 Pro XL(Android 15 QPR2 ベータ版 2 以降)