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, AOSP 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.
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. Without recompiling, apps might not work on 16 KB devices when they are productionized in future Android releases.
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).
Benefits and performance gains
Devices configured with 16 KB page sizes use slightly more memory on average, but also gain various performance improvements for both the system and apps:
- Lower app launch times while the system is under memory pressure: 3.16% lower on average, with more significant improvements (up to 30%) for some apps that we tested
- Reduced power draw during app launch: 4.56% reduction on average
- Faster camera launch: 4.48% faster hot starts on average, and 6.60% faster cold starts on average
- Improved system boot time: improved by 8% (approximately 950 milliseconds) on average
These improvements are based on our initial testing, and results on actual devices will likely differ. We'll provide additional analysis of potential gains for apps as we continue our testing.
Check if your app is impacted
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.
Does your app use native code?
Your app makes use of native code if any of the following apply:
- Your app uses any C/C++ (native) code. If your app uses the Android NDK, then your app uses native code.
- Your app links with any third-party native libraries or dependencies that use them.
- Your app is built by a third-party app builder that uses native libraries on device.
Identify native libraries using APK Analyzer
APK Analyzer is a tool that lets you evaluate various aspects of a built APK. To identify whether your app uses native code or libraries, follow these steps:
- Open Android Studio, then click File > Open and choose any project.
From the menu bar, click Build > Analyze APK...
Choose the APK you want to analyze.
Look within the
lib
folder, which hosts shared object (.so
) files if any are present. If any shared object files are present, your app uses native code. If no shared object files are present or there is nolib
folder, then your app doesn't use native code.
Build your app with support for 16 KB devices
To support 16 KB devices, apps that use native code should complete the steps that are outlined in the following sections. If you update to AGP version 8.5.1 or higher and NDK version r28 or higher, and use 16 KB-compatible prebuilt dependencies, then apps are 16 KB compatible by default.
Update the packaging of your shared libraries
We recommend that you upgrade to AGP version 8.5.1 or higher and use uncompressed shared libraries.
AGP version 8.5.1 or higher
16 KB devices require apps that ship with uncompressed shared libraries to align them on a 16 KB zip-aligned boundary. To do this, you need to upgrade to Android Gradle Plugin (AGP) version 8.5.1 or higher. Refer to the Android Gradle plugin Upgrade Assistant section for details on the upgrade process.
AGP version 8.5 or lower
If you can't upgrade AGP to version 8.5.1 or higher, then the alternative is to switch to use compressed shared libraries. Update your Gradle configuration to have Gradle compress your shared libraries when packaging your app to avoid app installation issues with unaligned shared libraries.
Groovy
In your build.gradle
file, add the following option:
android {
...
packagingOptions {
jniLibs {
useLegacyPackaging true
}
}
}
Kotlin
In your build.gradle.kts
file, add the following option:
android {
...
packagingOptions {
jniLibs {
useLegacyPackaging = true
}
}
}
Compile your app using 16 KB ELF alignment
16 KB devices require the shared libraries' ELF segments to be aligned properly using 16 KB ELF alignment in order for your app to run.
To compile your app using 16 KB ELF alignment, complete the steps in one of the following sections depending on the version of the Android NDK that you're using.
Android NDK r28 and higher
NDK version r28 and higher compile 16 KB-aligned by default.
Android NDK r27
To support compiling 16 KB-aligned shared libraries with Android NDK
version r27 and higher, you need to update your ndk-build
, build.gradle
,
build.gradle.kts
, or linker flags as follows:
ndk-build
In your Application.mk
:
APP_SUPPORT_FLEXIBLE_PAGE_SIZES := true
Groovy
In your build.gradle
file, set the 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
In your build.gradle.kts
file, set the 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")
}
}
}
}
Other build systems
Specify the following linker flags:
-Wl,-z,max-page-size=16384
Android NDK r26 and lower
To support compiling 16 KB-aligned shared libraries with Android NDK
version r26 or lower, you need to update your ndk-build
or cmake
configuration as follows:
ndk-build
Update your Android.mk
to enable 16 KB ELF alignment:
LOCAL_LDFLAGS += "-Wl,-z,max-page-size=16384"
CMake
Update your CMakeLists.txt
to enable 16 KB ELF alignment:
target_link_options(${CMAKE_PROJECT_NAME} PRIVATE "-Wl,-z,max-page-size=16384")
Check for code instances that reference specific page sizes
Even if your app is 16 KB-aligned, your app can encounter errors if places in your code assume that a device is using a specific page size. To avoid this, complete the following steps:
Remove any hard-coded dependencies that reference the
PAGE_SIZE
constant or instances in your code logic that assume that a device's page size is 4 KB (4096
).Use
getpagesize()
orsysconf(_SC_PAGESIZE)
instead.Look for usages of
mmap()
and other APIs that require page-aligned arguments and replace with alternatives where necessary.
In some cases, if your app uses PAGE_SIZE
as a convenient value that isn't
tied to the underlying page size, then this won't cause your app to break when
used in 16 KB mode. However, if this value is passed to the kernel with
mmap
without MAP_FIXED
, the kernel still uses an entire page, which wastes
some memory. For these reasons, PAGE_SIZE
is undefined when 16 KB mode is
enabled on NDK r27 and higher.
If your app uses PAGE_SIZE
in this way and never directly passes this value to
the kernel, then instead of using PAGE_SIZE
, create a new variable with a new
name to reflect that it is used for other purposes and does not reflect a real
memory page.
Test your app in a 16 KB environment
After you build your app with support for 16 KB devices, you'll want to test your app in a 16 KB environment to see whether your app experiences any regressions. To do this, follow these steps:
Set up one of the following testing environments:
Start up your test device, then run the following command to verify that it's using a 16 KB environment:
adb shell getconf PAGE_SIZE
The command should return a value of
16384
.For any shared libraries, verify that the shared libraries' ELF segments are aligned properly using 16 KB ELF alignment. You can use this script to help with this process:
#!/bin/bash # usage: alignment.sh path to search for *.so files dir="$1" RED="\e[31m" GREEN="\e[32m" ENDCOLOR="\e[0m" matches="$(find $dir -name "*.so" -type f)" IFS=$'\n' for match in $matches; do res="$(objdump -p ${match} | grep LOAD | awk '{ print $NF }' | head -1)" if [[ $res =~ "2**14" ]] || [[ $res =~ "2**16" ]]; then echo -e "${match}: ${GREEN}ALIGNED${ENDCOLOR} ($res)" else echo -e "${match}: ${RED}UNALIGNED${ENDCOLOR} ($res)" fi done
Save the script to a file, such as
alignment.sh
.Extract your app's APK file:
unzip APK_NAME.apk -d /tmp/my_apk_out ``` 1. Run the script on the extracted files in the `/tmp/my_apk_out` directory: ```none {: .devsite-terminal .devsite-click-to-copy } alignment.sh /tmp/my_apk_out | grep "arm64-v8a" ``` The script outputs either `ALIGNED` or `UNALIGNED` for all the `arm64-v8a` shared libraries. 1. If any `arm64-v8a` shared libraries are `UNALIGNED`, you'll need to [update the packaging for those libraries][20], then [recompile your app][21] and retest by following the steps in this section.
Run the following
zipalign
command to verify that your app is 16 KB-aligned, where APK_NAME is the name of your app's APK file:zipalign -c -P 16 -v 4 APK_NAME.apk
Thoroughly test your app, focusing on any areas that might be affected by changing code instances that reference specific page sizes.
Set up the Android Emulator with a 16-KB-based, Android 15 system image
To set up a 16 KB environment using the Android Emulator, follow these steps:
16-KB-based, Android 15 emulator system images are compatible with Android Studio Jellyfish | 2023.3.1 or higher. However, for the best experience when working with the Android 15 Beta, download the latest preview version of Android Studio.
Remember that you can keep your existing version of Android Studio installed, as you can install multiple versions side-by-side.
In Android Studio, click Tools > SDK Manager.
In the SDK Platforms tab, check Show Package Details, then expand the Android VanillaIceCream Preview section and select one or both of the following emulator system images, depending on the virtual devices you want to create:
- Google APIs Experimental 16k Page Size ARM 64 v8a System Image
- Google APIs Experimental 16k Page Size Intel x86_64 Atom System Image
Click Apply > OK to download whichever system images you selected.
Follow the steps to set up a virtual device for Android 15, and when prompted to select a system image, select the 16 KB system image that you downloaded. If it's not recommended automatically, you can find the 16 KB system image in the Other Images tab.
- In the Device manager, click the 3 dots next to the 16 KB image, then click Show on Disk.
- In this folder, find the
config.ini
file. Add the following line into the
config.ini
file and save your changes:kernel.parameters = androidboot.page_shift=14
To verify your changes, run the following command, which should return
16384
:adb shell getconf PAGE_SIZE
Enable 16 KB mode on a device using developer options
Starting with Android 15 QPR1, you can use the developer option that's available on certain devices to boot the device in 16 KB mode and perform on-device testing.
This developer option is available on the following devices:
- Pixel 8 and 8 Pro (with Android 15 QPR1 Beta 1 or higher)
- Pixel 8a (with Android 15 QPR1 Beta 2 or higher)