How to Adapt Android 15 Apps to 16K Page Size – A Complete Guide
This article walks through why Android 15’s 16 KB page size is a hidden trap for native libraries, shows how to locate 4 KB assumptions in code, and provides step‑by‑step CMake/Android‑mk adjustments, tooling commands, and debugging tips to ensure your .so files load correctly.
Android 15 changes the default memory page size from 4 KB to 16 KB, which breaks many native libraries that assume a 4 KB page. The article first explains the problem, then offers a practical workflow for adapting existing C/C++ code to the new page size.
Identify 4 KB Assumptions
Search the source tree for the literal 4096 used with mmap, sysconf or similar APIs. These occurrences indicate hard‑coded page‑size assumptions that must be updated.
Adjust Page‑Size Queries
Replace hard‑coded values with runtime queries such as getpagesize(). For example, add a log line: ALOGV("####### %d", getpagesize()); Running the app on an Android 15 emulator should now print 16384 instead of 4096.
Fix Linking Alignment
If the app crashes with an error like:
java.lang.UnsatisfiedLinkError: dlopen failed: empty/missing DT_HASH … (new hash type from the future?)the cause is usually that the generated .so file is not aligned to 16 KB. Depending on the build system, add the appropriate linker flag:
For CMake < 3.13: target_link_libraries(your_lib "-Wl,-z,max-page-size=16384") For CMake ≥ 3.13:
target_link_options(your_lib PRIVATE "-Wl,-z,max-page-size=16384")For Android.mk:
LOCAL_LDFLAGS += -Wl,-z,max-page-size=16384Verify Alignment with readelf
Use the NDK’s readelf tool to inspect the ELF headers before and after the change. The LOAD segment’s Align field should show 0x4000 (16384) instead of 0x1000 (4096).
./aarch64-linux-android-readelf -l /path/to/lib.soDebug Remaining Crashes
If the library still fails to load, employ addr2line to map crash addresses back to source lines:
/Users/guoshuyu/Library/Android/sdk/ndk/21.4.7075529/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/bin/aarch64-linux-android-addr2line -e /path/to/lib.so 0x7e0a0When addr2line returns ??, lower the optimization level in Application.mk (e.g., APP_CFLAGS := -O0) to retain debug symbols.
Handle C++ Standard Library Issues
Older NDK versions (< r27) may link against libc++_shared.so and cause similar errors. Solutions:
Upgrade to NDK r27 or newer.
Statically link the C++ runtime: add -DANDROID_STL=c++_static to the CMake arguments.
Static Variables and BSS Segment
Static globals reside in the .bss or .data sections. Mis‑aligned static variables can trigger SIGSEGV. Use readelf -S and grep _errMsg to verify the presence and alignment of such symbols.
Upgrade to NDK r27
When moving to NDK r27, ensure the project’s ndkVersion in build.gradle matches the installed version (e.g., ndkVersion '21.4.7075529'). Be aware that the bundled clang is version 18.1.0, supporting C++20/23, which may introduce new compilation warnings.
Risk Management
Upgrading the toolchain can expose previously hidden bugs. For large codebases (e.g., Tencent’s MMKV), evaluate compatibility carefully and test with minimal configuration changes before a full rollout.
Final Remarks
Successful adaptation requires access to the native source code. Without it, fixing the 16 KB page‑size requirement is impractical. Google plans to enforce 16 KB alignment on Play Store submissions, so developers should proactively update their builds.
Sohu Tech Products
A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
