2025 年 3 月 27 日より、AOSP のビルドとコントリビューションには aosp-main
ではなく android-latest-release
を使用することをおすすめします。詳細については、AOSP の変更をご覧ください。
16 KB ページサイズ
コレクションでコンテンツを整理
必要に応じて、コンテンツの保存と分類を行います。
ページサイズとは、OS がメモリを管理する際の粒度です。現在多くの CPU は、4 KB ページサイズをサポートしているため、Android OS やアプリは、4 KB ページサイズを実行できるようにビルド、最適化されてきました。ARM CPU は、より大きな 16 KB ページサイズをサポートしています。また、Android 15 以降、AOSP も 16 KB ページサイズでの Android のビルドをサポートしています。このオプションでは追加のメモリを使用しますが、システム パフォーマンスは向上します。Android 15 では、このオプションはデフォルトでは有効化されていませんが、デベロッパー モードまたはデベロッパー オプションとして利用できます。OEM やアプリ デベロッパーは、将来的にどこでも 16 KB モードに切り替えるための準備ができます。
Android 15 以降では、4 KB および 16 KB カーネルで動作する 16 KB ELF 配置での Android のビルド(android14-6.1
以降)がサポートされます。16 KB カーネルを使用する構成の場合、メモリを追加で消費することになりますが、システム パフォーマンスが改善されます。
Android ユーザー空間を 16 KB に設定する
16 KB ページがサポートされるのは、16 KB カーネルの arm64
ターゲットのみです。ただし、Cuttlefish の場合は、 x86_64
で 16 KB ユーザー空間をシミュレーションするオプションもあります。
arm64
ターゲットの場合、Kleaf でカーネルをビルドすると、--page_size=16k
が 16 KB モードでカーネルをビルドします。Linux カーネル設定を直接使用している場合、CONFIG_ARM64_4K_PAGES
の代わりに CONFIG_ARM64_16K_PAGES
を設定することで 16 KB ページを選択できます。
Android ユーザー空間で 16 KB ページサイズのサポートを有効化するには、次のビルド オプションを設定します。
PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true
: PAGE_SIZE
定義を削除し、実行時にコンポーネントがページサイズを決定するようにします。
PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384
: プラットフォーム ELF ファイルが確実に 16 KB アライメントで作成されるようにします。サイズが必要以上に大きいのは、今後の互換性を考慮しているためです。16 KB ELF アライメントでは、カーネルで 4 KB / 16 KB のページサイズをサポートできます。
ビルドフラグを確認する
lunch
ターゲットを選択したら、ビルドフラグが環境内で適切に設定されているか確認します。
$ source build/envsetup.sh
$ lunch target
$ get_build_var TARGET_MAX_PAGE_SIZE_SUPPORTED
16384
$ get_build_var TARGET_NO_BIONIC_PAGE_SIZE_MACRO
true
前の 2 つのコマンドで 16384
および true
がそれぞれ返された場合は、16 KB カーネルで動作させるためのビルドフラグが適切に設定されていることになります。ただ、ビルドが成功する場合でも、16 KB 環境の違いのために、ランタイムの問題が発生する場合があります。
16 KB ページサイズのシステム プログラミング
Android を搭載するデバイス上のコードのほとんどが、ページサイズを直接処理しません。ただ、ページを処理するコードの場合、カーネルのメモリ割り当ての動作が変化します。互換性があることに加え、パフォーマンスが最大限に優れ、リソース使用量が最小限に抑えられたコードを作成するためにも、このことに注意する必要があります。
4 KB システムで 1 KB、2 KB、あるいは 4 KB(最大)リージョンで mmap
を呼び出す場合、システムはこれを実装するために 4 KB を予約します。つまり、カーネルからメモリをリクエストする場合、カーネルは常にリクエストされたメモリを最も近いページサイズに切り上げる必要があります。たとえば、4 KB リージョンで 5 KB リージョンを割り当てる場合、カーネルは 8 KB を割り当てます。
16 KB カーネルの場合、ページのこの余分の「テールエンド」が大きくなります。たとえば、16 KB カーネルで使用される場合で、これらの割り当てのすべて(1 KB から 5 KB まで)を使用する場合、16 KB が割り当てられます。17 KB をリクエストすると、32 KB が割り当てられます。
たとえば、4 KB のシステムで、2 つの 4 KB 読み取り - 書き込み匿名リージョンを割り当てることは問題ありません。ただ、16 KB カーネルでこれを行うと、2 つのページ(32 KB)を割り当てることになります。16 KB カーネルでは、可能である場合にこれらのリージョンを単一の読み取りまたは書き込み可能なページに結合することができ、16 KB のみが使用されるようにすることができますが、4 KB カーネルの場合と比較して 8 KB が無駄になります。メモリ使用量をさらに抑えるには、ページをさらに結合します。実際、最大限に最適化された 16 KB システムでは、16 KB ページで要求されるメモリ量が 4 KB システムよりも少なく、これは、同じメモリに対するページテーブルのサイズが 1/4 になっているためです。
mmap
を使用する場合は常に、リクエストするサイズが最も近いページサイズに切り上げられるようにします。これにより、カーネルが割り当てるメモリの全量がランタイムの値で直接ユーザー空間に表示されるようになり、暗示的にリクエストされる、あるいは暗示的または偶発的にアクセス可能になることがなくなります。
16 KB ELF アライメントで共有ライブラリをビルドする
Android プロジェクトの一部である共有ライブラリをビルドするには、「16 KB ページサイズを有効にする」の前の設定で十分です。
PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true
PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384
Android プロジェクトの一部ではない共有ライブラリをビルドする場合は、以下のリンカーフラグを渡す必要があります。
-Wl,-z,max-page-size=16384
16 KB ELF アライメントのバイナリおよび事前ビルドを確認する
アライメントと実行時の動作を確認するのに最適な方法は、コンパイルされた 16 KB カーネルでテスト、実行することです。ただし、次の方法で早期に問題を検出できます。
Android 16(AOSP 試験運用版)以降、ビルド時に PRODUCT_CHECK_PREBUILT_MAX_PAGE_SIZE := true
を設定できます。一時的に無視するには、Android.bp
で ignore_max_page_size: true
を、Android.mk
で LOCAL_IGNORE_MAX_PAGE_SIZE := true
を使用します。これらの設定により、すべての事前ビルドを確認し、16 KB アライメントではない更新済みのビルドを検出できます。
Android 15 以降でリリースされるデバイスでは、atest elf_alignment_test
を実行してデバイス上の ELF ファイルのアライメントを確認できます。
このページのコンテンツやコードサンプルは、コンテンツ ライセンスに記載のライセンスに従います。Java および OpenJDK は Oracle および関連会社の商標または登録商標です。
最終更新日 2025-03-26 UTC。
[[["わかりやすい","easyToUnderstand","thumb-up"],["問題の解決に役立った","solvedMyProblem","thumb-up"],["その他","otherUp","thumb-up"]],[["必要な情報がない","missingTheInformationINeed","thumb-down"],["複雑すぎる / 手順が多すぎる","tooComplicatedTooManySteps","thumb-down"],["最新ではない","outOfDate","thumb-down"],["翻訳に関する問題","translationIssue","thumb-down"],["サンプル / コードに問題がある","samplesCodeIssue","thumb-down"],["その他","otherDown","thumb-down"]],["最終更新日 2025-03-26 UTC。"],[],[],null,["# 16 KB page size\n\nPage size is the granularity at which an OS manages memory. Most CPUs today\nsupport a 4 KB page size and so the Android OS and apps have\nhistorically been built and optimized to run with a 4 KB page size. ARM\nCPUs support the larger 16 KB page size, and starting in Android\n15, AOSP has support for building Android with a\n16 KB page size as well. This option uses additional memory but improves\nsystem performance. As of Android 15, this option isn't\nenabled by default, but it is available as a developer mode or a developer\noption for OEMs and app developers to prepare for switching to 16 KB mode\neverywhere in the future.\n\nAndroid 15 and higher have support for building\nAndroid with a 16 KB ELF alignment, which works with 4 KB and\n16 KB kernels starting with\n[`android14-6.1`](https://android.googlesource.com/kernel/common/+/refs/heads/android14-6.1).\nWhen used with a 16 KB kernel, this configuration uses additional memory\nbut improves system performance.\n\nSet Android to 16 KB\n--------------------\n\n16 KB pages are only supported on `arm64` targets with 16 KB kernels.\nHowever, there is also an option to\n[simulate 16 KB userspace on `x86_64`](/docs/core/architecture/16kb-page-size/getting-started-cf-x86-64-pgagnostic) for Cuttlefish.\n\n### Kernel space\n\nFor `arm64` targets, if you use\n[Kleaf](https://android.googlesource.com/kernel/build/+/refs/heads/main/kleaf/docs/kleaf.md)\nto build your kernel, `--page_size=16k` builds the kernel in 16 KB mode.\nIf you are directly using Linux kernel configuration, you can select 16 KB\npages by setting `CONFIG_ARM64_16K_PAGES` instead of `CONFIG_ARM64_4K_PAGES`.\n\n### User space\n\nTo enable 16 KB page size support in Android user space, set the following\nbuild options on your product:\n\n- `PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true` removes the `PAGE_SIZE` define, and it makes components determine page size at runtime.\n- `PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384` which ensures platform ELF files are built with 16 KB alignment. This larger-than-needed size is for future compatibility. With 16 KB ELF alignment, the kernel can support 4 KB/16 KB page sizes.\n\nVerify build flags\n------------------\n\nAfter selecting the `lunch` target, verify that the build flags are set up\ncorrectly in the environment: \n\n $ source build/envsetup.sh\n $ lunch \u003cvar translate=\"no\"\u003etarget\u003c/var\u003e\n\n $ get_build_var TARGET_MAX_PAGE_SIZE_SUPPORTED\n 16384\n $ get_build_var TARGET_NO_BIONIC_PAGE_SIZE_MACRO\n true\n\nIf the previous two commands return `16384` and `true` respectively, your build\nflags are set up correctly to work with a 16 KB kernel. However, even if\na build passes, there might still be runtime issues due to differences in a\n16 KB environment.\n\n16 KB page size system programming\n----------------------------------\n\nThe vast majority of code on any Android-powered device doesn't directly deal\nwith page size. However, for code that deals with pages, the kernel's memory\nallocation behavior changes, and you need to keep this in mind to write code\nthat is not only compatible but also maximally performant and minimally\nresource intensive.\n\nIf you call `mmap` on a 1 KB, 2 KB, or up to a 4 KB region on a\n4 KB system, the system reserves 4 KB to implement this. In other\nwords, when requesting memory from the kernel, the kernel must always round up\nthe requested memory to the nearest page size. For example, if you allocate a\n5 KB region on a 4 KB region, the kernel allocates 8 KB.\n\nOn a 16 KB kernel, these extra \"tail ends\" of pages are larger.\nFor example, all of these allocations, from 1 KB to 5 KB would\nallocate 16 KB when used with a 16 KB kernel. If you request\n17 KB, it allocates 32 KB.\n\nFor example, on a 4 KB system, it's okay to allocate two 4 KB\nread-write anonymous regions. However, on a 16 KB kernel, this would result\nin allocating two pages or 32 KB. On a 16 KB kernel, if possible,\nthese regions can be combined into a single read or writeable page so that only\n16 KB is used, wasting 8 KB compared to the 4 KB kernel case. To\nreduce even more memory usage, more pages can be combined. In fact, on a\n16 KB system that is maximally optimized, 16 KB pages require less\nmemory than 4 KB systems because the page table is one fourth the size\nfor the same memory.\n\nWhenever using `mmap`, ensure that you round the size you are requesting up to\nthe nearest page size. This ensures that the entire amount of memory the kernel\nallocates is directly visible to userspace in runtime values, instead of being\nimplicitly requested and implicitly or accidentally accessible.\n\nBuild shared libraries with 16 KB ELF alignment\n-----------------------------------------------\n\nTo build shared libraries that are part of the\n[android project](https://cs.android.com/android/platform/superproject/main),\nthe earlier settings in [Enable 16 KB page size](#enable-16kb) are sufficient:\n\n- `PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true`\n- `PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384`\n\nTo build shared libraries that aren't part of\n[android project](https://cs.android.com/android/platform/superproject/main),\nyou need to pass this linker flag: \n\n -Wl,-z,max-page-size=16384\n\nVerify binaries and prebuilts for 16 KB ELF alignment\n-----------------------------------------------------\n\nThe best way to verify alignment and runtime behavior is to test and run on a\n16 KB compiled kernel. However, in order to catch some issues earlier:\n\n- Starting in Android 16, you can set\n `PRODUCT_CHECK_PREBUILT_MAX_PAGE_SIZE := true` at build time. Use\n `ignore_max_page_size: true` in `Android.bp` and\n `LOCAL_IGNORE_MAX_PAGE_SIZE := true` in `Android.mk` to temporarily ignore\n them. These settings verify all prebuilts and allow you to detect when one\n is updated but is not 16 KB aligned.\n\n- You can run `atest elf_alignment_test` which verifies the alignment of\n on-device ELF files on devices launching with\n Android 15 and later."]]