頁面大小是作業系統管理記憶體的細微程度。現今大多數 CPU 都支援 4 KB 分頁大小,因此 Android OS 和應用程式過去都是以 4 KB 分頁大小建構及最佳化。ARM CPU 支援較大的 16 KB 分頁大小,而從 Android 15 開始,AOSP 也支援建構採用 16 KB 分頁大小的 Android。這個選項會使用額外記憶體,但可提升系統效能。在 Android 15 中,這項選項預設為停用,但 OEM 和應用程式開發人員可以透過開發人員模式或開發人員選項啟用,為日後全面切換至 16 KB 模式做好準備。
Android 15 以上版本支援以 16 KB ELF 對齊方式建構 Android,可搭配 4 KB 和 16 KB 核心使用,從 android14-6.1
開始支援。搭配 16 KB 核心使用時,這項設定會使用額外記憶體,但可提升系統效能。
將 Android 設為 16 KB
16 KB 頁面僅適用於具有 16 KB 核心的 arm64
目標。
不過,您也可以選擇在 Cuttlefish 上模擬 16 KB 的使用者空間x86_64
。
核心空間
如果是 arm64
目標,如果您使用 Kleaf 建構核心,--page_size=16k
會以 16 KB 模式建構核心。如果您直接使用 Linux 核心設定,可以設定 CONFIG_ARM64_16K_PAGES
(而非 CONFIG_ARM64_4K_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
如果前兩個指令分別傳回 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 系統上,可以分配兩個 4 KB 的讀寫匿名區域。不過,在 16 KB 核心上,這會導致分配兩個頁面或 32 KB。在 16 KB 核心上,如果可以,這些區域可以合併為單一可讀取或可寫入的頁面,這樣就只會使用 16 KB,與 4 KB 核心的情況相比,會浪費 8 KB。如要進一步減少記憶體用量,可以合併更多頁面。事實上,在經過最佳化處理的 16 KB 系統中,16 KB 頁面所需的記憶體比 4 KB 系統更少,因為相同記憶體的分頁表大小只有四分之一。
使用 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 開始,您可以在建構時設定
PRODUCT_CHECK_PREBUILT_MAX_PAGE_SIZE := true
。在Android.bp
中使用ignore_max_page_size: true
,以及在Android.mk
中使用LOCAL_IGNORE_MAX_PAGE_SIZE := true
,暫時忽略這些項目。這些設定會驗證所有預先建構的項目,並在項目更新但未與 16 KB 對齊時偵測到。您可以執行
atest elf_alignment_test
,驗證在搭載 Android 15 以上版本的裝置上啟動時,裝置上 ELF 檔案的對齊方式。