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

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, Android 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.

Devices with larger page sizes can have improved performance for memory-intensive workloads. 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. We plan to make 16 KB page compatibility required for app uploads to the Google Play store next year.

As device manufacturers continue to build devices with larger amounts of physical memory (RAM), many of these devices will likely be configured with 16 KB (and eventually greater) page sizes to optimize the device's performance. Adding support for 16 KB devices enables your app to run on these devices and helps your app benefit from the associated performance improvements.

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

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

配置为 16 KB 页面的设备平均使用的内存会略多,但系统和应用性能也会有所提升:

  • 在系统面临内存压力时缩短应用启动时间:平均降低了 3.16%,对于我们测试过的一些应用而言,改进幅度更显著(提升幅度高达 30%)
  • 降低应用启动时的功耗:平均降低 4.56%
  • 相机启动速度更快:平均热启动速度加快 4.48%,冷启动速度平均加快 6.60%
  • 缩短了系统启动时间:平均缩短了 1.5%(约 0.8 秒)

这些改进基于我们的初始测试,实际设备上的结果可能会有所不同。在继续测试的过程中,我们会进一步分析应用的潜在益处。

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

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 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 ビュー

16 KB デバイスに対応したアプリをビルドする

16 KB デバイスをサポートするには、ネイティブ コードを使用するアプリで以降のセクションで説明する手順を完了する必要があります。

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

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

AGP バージョン 8.3 以降

16 KB のデバイスでは、出荷時に共有ライブラリが圧縮されていない状態で、アプリを 16 KB の zip 調整境界に揃える必要があります。そのためには、Android Gradle プラグイン(AGP)バージョン 8.3 以降にアップグレードする必要があります。アップグレード プロセスの詳細については、Android Gradle プラグイン Upgrade Assistant のセクションをご覧ください。

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
      }
  }
}

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

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

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

Android NDK r26 以前

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

ndk-build

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

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

CMake

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

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

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

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

アプリが 16 KB 単位で調整されていても、コード内の場所からデバイスで特定のページサイズが使用されていると想定すると、アプリでエラーが発生する場合があります。これを回避するには、次の操作を行います。

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

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

  2. ページ揃えの引数を必要とする mmap() やその他の API を使用しているかどうかを確認し、必要に応じて代替に置き換えます。

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

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

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

16 KB デバイスをサポートするアプリをビルドしたら、16 KB の環境でアプリをテストし、アプリで回帰が発生しないかどうかを確認することをおすすめします。これを行うには、次のいずれかのテスト環境をセットアップしてから、特定のページサイズを参照するコード インスタンスを変更することで影響を受ける可能性のある部分を中心に、アプリを徹底的にテストします。

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 API 試験運用版 16k ページサイズ ARM 64 v8a システム イメージ
    • Google API 試験運用版 16k ページサイズ Intel x86_64 Atom システム イメージ

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

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

  5. 手順に沿って Android 15 の仮想デバイスをセットアップし、システム イメージの選択を求められたら、ダウンロードした 16 KB のシステム イメージを選択します。自動的に推奨されない場合は、[Other Images] タブに 16 KB のシステム イメージが表示されます。

    [その他のイメージ] タブで 16 KB のエミュレータ イメージを確認する