Android 15 대응 - 16KB Page Size
문제 상황
Android 15가 되며 16KB memory page size가 허용 되었습니다.
이전까지는 4KB memory page size만이 허용되었고, 이 변화는 눈에 띄는 성능 향상을 가져왔습니다.
앱 실행시간 : 평균 3.16% 감소
앱 실행 중 전력 소모 감소 : 평균 4.56% 감소
카메라 실행 속도 : 평균 Hot Start - 4.48%, Cold Start - 6.60% 감소
시스템 부팅 속도 : 평균 8% 감소
왜 대응해야 할까?
Android 15에서 memory page size가 4KB로 고정이었다가 16KB가 가능하게 되었습니다.
즉, Android 15부터 16KB ELF 정렬을 사용해서 Android를 빌드할 수 있게 되었습니다.
ELF 정렬이란?
메모리에 데이터를 배치할 때 특정 주소 경계(boundary)에 맞춰 배치하는 것.
예를 들어 데이터가 4바이트라면 메모리의 주소가 4의 배수인 위치에 배치됩니다.
ex) 0x00, 0x04, 0x08…
ELF 정렬을 통해 CPU가 특정 경계에 맞춰 데이터를 읽을 수 있기에 성능이 최적화되어 더 빠르고 안전하게 접근할 수 있습니다.
왜 ELF 정렬이 메모리 페이지 크기랑 관련 있을까?
메모리 페이지 크기는 OS가 메모리를 관리할 때 최소 단위를 의미합니다.
즉, ELF 파일의 세그먼트는 페이지 크기 경계에 맞춰 메모리에 로드 돼야 합니다.
결론
만약 ELF 파일이 4KB 기준으로만 정렬돼 있으면, 16KB 페이지 크기에서 성능에 문제가 생기거나 제대로 동작하지 않을 수 있습니다.
대응을 위한 체크리스트
네이티브 코드(C / C++)를 사용하나요?
사용하는 모든 라이브러리 및 앱 내부 코드가 java, kotlin만 존재한다면 대응하지 않아도 됩니다.
사용하는지 않는지 판단하기 힘들다면 APK Analyzer를 사용하여 확인해주세요.
APK Analyzer를 사용한 결과 lib 패키지 안에 arm64-v8a / armeabi-v7a 가 존재하므로 네이티브 코드가 존재하는 것으로 추론됩니다.
네이티브 코드를 사용한다면 아래 단계를 따라주세요.
- Android Gradle Plugin(AGP)를 8.5.1 이상으로 업데이트 하세요.
-불가능 하다면 build.gradle에 아래 코드를 추가해주세요
// 단, 라이브러리가 apk에서 추출되어 디스크에 복사되므로 앱이 설치될 때 더 많은 공간을 차지하게 됩니다.
android {
...
packagingOptions {
jniLibs { useLegacyPackaging true }
}
}
- ELF 정렬을 위해 NDK를 대응해주세요. Application.mk 파일에 아래 내용을 추가해주면 됩니다.
- Android NDK r28 이상 : 기본적으로 16KB 정렬을 컴파일 하기에 대응하지 않아도 됩니다.
- Android NDK r27 이상 : build.gradle 파일에서 인수 -DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON를 설정합니다.
- Android NDK r26 이하
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"
}
}
}
}
- 16KB ELF 정렬을 사용 설정하도록 Android.mk를 업데이트합니다. LOCAL_LDFLAGS += "-Wl,-z,max-page-size=16384"
- NDK : Andorid NDK는 C 및 C++과 같은 언어를 사용하여 앱의 일부를 네이티브 코드로 구현할 수 있는 도구 모음.
이때, 제가 작업하는 프로젝트에서는 NDK가 설정되어있지 않았습니다.
즉, 저희가 자체적으로 구현해둔 것이 아닌, 저희가 쓰고있는 라이브러리/SDK에서 사용하고 있다는 것을 의미합니다.
그렇기에 라이브러리와 SDK를 확인해서 버전 업데이트를 해야 합니다.
lib 폴더만 있다고 하더라고 대응이 되어있다면 문제 없습니다.
공식문서에 있는 확인 방법을 통해 확인하면 됩니다.
SDK 및 라이브러리가 16KB 대응이 되는 버전을 사용해주세요.
앱 내부 코드가 전부 대응이 되어있더라도 SDK 혹은 Library에 문제가 있다면 앱에 영향을 끼칠 수 있습니다.
최신 배포 버전을 확인하고, 대응이 된 버전을 사용하는 것을 권장합니다.
특정 PAGE_SIZE를 4KB(4096)으로 가정하는 코드가 있나요?
PAGE_SIZE가 기존에는 4KB 고정이었지만 이제 16KB가 가능하게 되어 이는 문제가 발생할 수 있습니다.
4KB(4096)이라는 Magic Number를 제거해주시기 바랍니다.
대신 getpagesize() 또는 sysconf(_SC_PAGESIZE)를 사용하세요.
어떻게 테스트 할 수 있을까?
가상기기(Emulator)에 설정하여 테스트 할 수 있습니다.
Android 15 QPR1 : Pixel 8, 8a, 8 Pro
Android 15 QPR2 Beta 2 : Pixel 9, 9 Pro, 9 Pro XL
관련 공식문서
https://developer.android.com/guide/practices/page-sizes
https://source.android.com/docs/core/architecture/16kb-page-size/16kb?hl=ko