Исторически Android поддерживал страницы памяти размером всего 4 КБ, что оптимизировало производительность системной памяти для среднего объёма памяти, обычно используемого устройствами Android. Начиная с Android 15, AOSP поддерживает устройства, настроенные на использование страниц размером 16 КБ (устройства с 16 КБ). Если ваше приложение использует библиотеки NDK , напрямую или косвенно через SDK, вам потребуется пересобрать приложение для его работы на устройствах с 16 КБ.
Поскольку производители устройств продолжают выпускать устройства с большим объёмом физической памяти (ОЗУ), многие из них будут использовать размер страницы 16 КБ (а в перспективе и больше) для оптимизации производительности. Добавление поддержки устройств с размером страницы 16 КБ позволит вашему приложению работать на этих устройствах и позволит использовать преимущества, связанные с повышением производительности. Без перекомпиляции приложения не будут работать на устройствах с 16 КБ в будущих версиях Android.
Чтобы помочь вам добавить поддержку для вашего приложения, мы предоставили рекомендации о том, как проверить, затронуто ли ваше приложение , как перестроить ваше приложение (если это применимо) и как протестировать ваше приложение в среде 16 КБ с помощью эмуляторов (включая образы системы Android 15 для эмулятора Android).
Требования к совместимости с Google Play
Чтобы приложение корректно работало в последних версиях Android, все приложения, предназначенные для Android 15 (уровень API 35) и более поздних версий, должны поддерживать страницы памяти размером 16 КБ на 64-битных устройствах в Google Play. С 1 февраля 2027 года вы не сможете выпускать обновления приложения, если они не поддерживают страницы памяти размером 16 КБ.
Преимущества и повышение эффективности
Устройства, настроенные с размером страницы 16 КБ, в среднем используют немного больше памяти, но также получают различные улучшения производительности как для системы, так и для приложений:
- Сокращение времени запуска приложений, когда система испытывает нехватку памяти: в среднем на 3,16 % меньше, с более значительными улучшениями (до 30 %) для некоторых протестированных нами приложений.
- Снижение энергопотребления при запуске приложения: в среднем снижение на 4,56 %.
- Более быстрый запуск камеры: в среднем на 4,48 % более быстрый горячий запуск и в среднем на 6,60 % более быстрый холодный запуск.
- Улучшено время загрузки системы: в среднем улучшено на 8% (приблизительно 950 миллисекунд).
Эти улучшения основаны на нашем первоначальном тестировании, и результаты на реальных устройствах, вероятно, будут отличаться. По мере продолжения тестирования мы предоставим дополнительный анализ потенциальных преимуществ для приложений.
Как проверить, затронули ли изменения ваше приложение
Если ваше приложение использует нативный код , вам следует пересобрать его с поддержкой устройств с памятью 16 КБ . Если вы не уверены, использует ли ваше приложение нативный код, вы можете использовать APK Analyzer для его определения, а затем проверить выравнивание сегментов ELF для любых обнаруженных общих библиотек . Android Studio также предоставляет функции, помогающие автоматически обнаруживать проблемы выравнивания .
Если ваше приложение использует только код, написанный на языке программирования Java или Kotlin, включая все библиотеки и SDK, то оно уже поддерживает устройства с 16 КБ. Тем не менее, мы рекомендуем протестировать приложение в среде с 16 КБ, чтобы убедиться в отсутствии непредвиденных регрессий в его поведении.
Используется ли в вашем приложении нативный код?
В вашем приложении используется нативный код, если выполняется любое из следующих условий:
- В приложении используется нативный код C/C++. Если в вашем приложении используется Android NDK, значит в нем есть нативный код.
- Ваше приложение связано со сторонними нативными библиотеками или зависимостями (например, SDK), которые используют эти функции.
- Ваше приложение создано с помощью стороннего конструктора, который использует нативные библиотеки на устройстве.
Как найти нативные библиотеки с помощью APK Analyzer
Анализатор APK – это инструмент, который позволяет оценивать различные аспекты созданного APK-файла. Чтобы проверить, использует ли ваше приложение нативный код (независимо от того, совместим ли он со страницами памяти размером 16 КБ):
- Откройте Android Studio, нажмите File (Файл) > Open (Открыть) и выберите любой проект.
В строке меню выберите Build (Сборка) > Analyze APK (Анализ APK).
Выберите APK-файл, который хотите проанализировать.
Проверьте папку
lib, в которой хранятся файлы общих объектов (.so), если они есть. Если в приложении есть файлы общих объектов, значит оно использует нативный код. В столбце Выравнивание показываются предупреждения о файлах, в которых есть проблемы с выравниванием. Если общих объектных файлов нет или отсутствует папкаlib, значит в приложении не используется нативный код.
Как выявлять проблемы с выравниванием с помощью автоматических проверок
Android Studio заранее предупреждает, если ваши предварительно созданные библиотеки или APK несовместимы с размером страницы 16 КБ. Используйте инструмент APK Analyzer, чтобы проверить, какие библиотеки нужно обновить и требуются ли изменения в коде.
Инструмент Lint в Android Studio также выделяет нативные библиотеки, которые не выровнены по 16 КБ.
Проверьте выравнивание сегментов ELF для общих библиотек
Убедитесь, что сегменты ELF общих библиотек выровнены по размеру 16 КБ. Если вы разрабатываете приложение в Linux или macOS, то можете использовать скрипт check_elf_alignment.sh, как описано в следующем разделе. Вы также можете использовать инструменты командной строки напрямую.
Как использовать скрипт check_elf_alignment.sh (Linux или macOS)
Чтобы проверить выравнивание сегментов ELF с помощью скрипта check_elf_alignment.sh, выполните следующие действия:
Сохраните скрипт
check_elf_alignment.shв файл.Запустите скрипт для APK-файла приложения:
check_elf_alignment.sh APK_NAME.apkСкрипт выводит
ALIGNEDилиUNALIGNEDдля всех общих библиотекarm64-v8a.Если какие-либо общие библиотеки
arm64-v8aилиx86_64UNALIGNED, вам нужно будет обновить упаковку этих библиотек, а затем перекомпилировать приложение и повторно протестировать его, выполнив описанные в этом разделе действия.
Используйте инструменты командной строки напрямую
Чтобы проверить выравнивание сегментов ELF с помощью инструментов командной строки, выполните следующие действия:
- Убедитесь, что с помощью SDK Manager в Android Studio или инструмента командной строки
sdkmanagerустановлены Android SDK Build-Tools версии 35.0.0 или более поздней и Android NDK. Извлеките APK-файл приложения.
Linux или macOS
unzip APK_NAME.apk -d /tmp/my_apk_outWindows (PowerShell)
Expand-Archive -Path .\APK_NAME.apk -DestinationPath ~\tmp\my_apk_outВременный каталог, в который вы извлекли APK-файл, содержит каталог
libс файлами общего объекта (.so). Это те же файлы общих объектов, которые вы могли видеть при определении нативных библиотек с помощью APK Analyzer. Выполните следующую команду для каждого файла общего объекта:Linux или macOS
SDK_ROOT_LOCATION/Android/sdk/ndk/NDK_VERSION/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-objdump -p SHARED_OBJECT_FILE.so | grep LOADWindows (PowerShell)
SDK_ROOT_LOCATION\Android\sdk\ndk\NDK_VERSION\toolchains\llvm\prebuilt\windows-x86_64\bin\llvm-objdump.exe -p SHARED_OBJECT_FILE.so | Select-String -Pattern "LOAD"где
SDK_ROOT_LOCATION– путь к каталогу, в котором установлен Android SDK,SHARED_OBJECT_FILE– название проверяемого файла общего объекта, аNDK_VERSION– версия установленного Android NDK (например,28.0.12433566). Для каждого проверяемого файла будет выводиться примерно следующая информация:LOAD off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**14 LOAD off 0x0000000000042a90 vaddr 0x0000000000043a90 paddr 0x0000000000043a90 align 2**14 LOAD off 0x0000000000046230 vaddr 0x0000000000048230 paddr 0x0000000000048230 align 2**14Убедитесь, что в выходных строках нет значений меньше
2**14. Если для каких-либо сегментов загрузки указаны значения2**13,2**12или ниже, вам нужно обновить упаковку этих библиотек, а затем перекомпилировать приложение и повторно протестировать его, следуя инструкциям в этом разделе.Затем запустите инструмент командной строки
zipalignдля APK-файла приложения:Linux или macOS
SDK_ROOT_LOCATION/Android/sdk/build-tools/35.0.0/zipalign -v -c -P 16 4 APK_NAME.apkWindows (PowerShell)
SDK_ROOT_LOCATION\Android\sdk\build-tools\35.0.0\zipalign.exe -v -c -P 16 4 APK_NAME.apkгде
SDK_ROOT_LOCATION– путь к каталогу, в котором установлен Android SDK, аAPK_NAME– название APK-файла приложения. Если все общие библиотеки выровнены правильно, в последней строке выходных данных будет написано "Verification successful" (Проверка выполнена успешно).Если проверка не пройдена, некоторые общие библиотеки нужно перенастроить. Для этого обновите упаковку этих библиотек, перекомпилируйте приложение и повторно выполните описанные в этом разделе действия.
Проверьте флаг безопасности RELRO
Чтобы снизить риск уязвимостей, современные компоновщики используют флаг Relocation Read-Only (RELRO), который делает разделы перемещения в общем объектном файле доступными только для чтения после загрузки. Включите флаг RELRO в сборке.
Если начальный адрес и размер сегмента (MemSize) раздела RELRO не выровнены по 16 КБ, приложение во время выполнения завершается с ошибкой сегментации. Это происходит, если файл .so был создан с помощью цепочки инструментов NDK r27 или более ранней версии без включения соответствующих флагов.
Выполните следующую команду для каждого файла общего объекта (Linux или macOS):
SDK_ROOT_LOCATION/Android/sdk/ndk/NDK_VERSION/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-readelf -Wl SHARED_OBJECT_FILE.so | grep 'RELRO\|Type'
Строка GNU_RELRO выводится, если есть сегмент RELRO.
Затем проверьте выравнивание сегмента RELRO. Для этого сложите его виртуальный адрес смещения (VirtAddr) с размером памяти сегмента (MemSiz) и разделите на 16 КБ (0x4000). Если остаток (модуль) равен нулю, то сегмент RELRO выровнен по размеру страницы 16 КБ.
Пример несопоставленного файла .so:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
GNU_RELRO 0x0cfaf0 0x00000000000dfaf0 0x00000000000dfaf0 0x01510 0x01510 R 0x1
Формула: (VirtAddr + MemSiz) % 0x4000 == 0
Результат: (0xdfaf0 + 0x01510) % 0x4000 = 0xE1000 % 0x4000 == 0x1000
Поскольку 0x1000 не равно нулю, этот файл .so не поддерживает страницы памяти объемом 16 КБ. Диапазон защиты RELRO от DC000 (предыдущий разрыв страницы) до E4000 доступен только для чтения, но Android Linker ожидает, что поддиапазон от E1000 до E4000 будет доступен для записи, что приводит к ошибке сегментации. В этом случае пересоберите файл .so, как описано в разделе Компилируйте приложение с выравниванием ELF по 16 КБ.
Ниже приведен пример выровненного файла .so с сегментом RELRO.
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
GNU_RELRO 0x0cfaf0 0x00000000000dfaf0 0x00000000000dfaf0 0x01510 0x00510 R 0x1
Пример файла .so без сегмента RELRO:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
Это тривиальный файл .so, соответствующий требованиям к размеру страницы 16 КБ, без сегмента RELRO.
Ниже приведен пример выровненного файла .so, в котором GNU_RELRO находится в собственном сегменте LOAD:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x000680 0x000680 R E 0x4000
LOAD 0x000680 0x0000000000004680 0x0000000000004680 0x0001d8 0x000980 RW 0x4000
GNU_RELRO 0x000680 0x0000000000004680 0x0000000000004680 0x0001d8 0x000980 R 0x1
Формула: (VirtAddr + MemSiz) % 0x4000 == 0
Результат: (0x4680 + 0x0980) % 0x4000 = 0x5000 % 0x4000 == 0x1000
Хотя значение 0x1000 не равно нулю, файл .so соответствует требованиям к размеру страницы 16 КБ.
Формула модуля применяется, когда GNU_RELRO делит сегмент LOAD с последующими доступными для записи данными (например, .data или .bss).
Чтобы проверить, находится ли GNU_RELRO в собственном сегменте LOAD, изучите заголовки программы, запустив llvm-readelf -Wl и отфильтровав результаты с помощью grep 'LOAD\|RELRO\|Type'. Сравните VirtAddr и MemSiz GNU_RELRO с содержащим сегментом LOAD. В этом примере у обоих есть VirtAddr 0x4680 и MemSiz 0x0980.
Поскольку весь сегмент LOAD содержит только данные RELRO, в поддиапазоне от 0x5000 до 0x8000 нет данных, доступных для записи. Кроме того, любой последующий сегмент LOAD, доступный для записи, начинается на отдельной границе страницы размером 16 КБ (0x8000 или выше). Защита компоновщика от записи не будет перекрываться с данными, доступными для записи, поэтому ошибка сегментации не возникнет.
Как создать приложение с поддержкой устройств с размером страницы 16 КБ
Если в вашем приложении используется нативный код, выполните действия, описанные в разделах ниже, чтобы обеспечить поддержку устройств с размером страниц памяти 16 КБ.
- Обновите упаковку общих библиотек
- Скомпилируйте приложение с выравниванием ELF-файлов по границе 16 КБ
- Исправление кода и устранение проблем во время выполнения
- Оптимизируйте специальные распределители памяти (если применимо)
- Как проверить, поддерживают ли SDK размер страницы 16 КБ
Обновите упаковку общих библиотек
Перейдите на AGP версии 8.5.1 или выше и используйте несжатые общие библиотеки.
Используйте bundletool, чтобы проверить выравнивание молнии
Чтобы посмотреть, как выровнен набор, используйте:
bundletool dump config --bundle=<my .aab> | grep alignment
Если вы видите PAGE_ALIGNMENT_16K, значит ваш пакет требует выравнивания по 16 КБ. Если вы видите PAGE_ALIGNMENT_4K, это означает, что в APK, созданном из этого AAB, должны быть файлы .so, выровненные по 4 КБ в ZIP-файле.
AGP версии 8.5.1 или более поздней;
На устройствах с поддержкой 16 КБ приложения, которые поставляются с несжатыми общими библиотеками, должны выравнивать их по границе 16 КБ. Для этого вам нужно обновить плагин Android Gradle (AGP) до версии 8.5.1 или более поздней. Подробнее о процессе обновления можно узнать в разделе Помощник по обновлению плагина Gradle для Android.
AGP версии 8.5 или ниже
Если вы не можете обновить AGP до версии 8.5.1 или более поздней, используйте сжатые общие библиотеки. Обновите конфигурацию Gradle, чтобы Gradle сжимал общие библиотеки при упаковке приложения. Это поможет избежать проблем с установкой приложения из-за несовместимости общих библиотек.
Яркий
Добавьте в файл build.gradle следующий параметр:
android {
...
packagingOptions {
jniLibs {
useLegacyPackaging true
}
}
}
Kotlin
Добавьте в файл build.gradle.kts следующий параметр:
android {
...
packagingOptions {
jniLibs {
useLegacyPackaging = true
}
}
}
AGP версии 8.0 или более ранней.
Если вы используете AGP версии 8.0 или ниже, вам также нужно отключить параметр несжатой нативной библиотеки для наборов App Bundle в файле gradle.properties:
android.bundle.enableUncompressedNativeLibs=false
Как скомпилировать приложение с выравниванием ELF-файлов по границе 16 КБ
Чтобы приложение работало на устройствах со страницами памяти размером 16 КБ, сегменты ELF общих библиотек должны быть выровнены по размеру 16 КБ.
Если вы разрабатываете игры на игровом движке Unity, ознакомьтесь с руководством по Unity. Если ваша игра работает на игровом движке Unreal, ознакомьтесь с руководством по Unreal.Если вы используете другой движок, следуйте инструкциям ниже.
Чтобы скомпилировать приложение с выравниванием ELF-файлов по размеру 16 КБ, выполните действия из одного из следующих разделов в зависимости от используемой версии Android NDK.
Android NDK r28 и более поздние версии
NDK версии r28 и выше по умолчанию компилирует библиотеки с выравниванием по 16 КБ.
Android NDK r27 и более ранние версии
Чтобы скомпилировать общие библиотеки, поддерживающие страницы памяти размером 16 КБ, с помощью Android NDK версии r27 или более ранней, используйте следующие флаги компоновщика:
-Wl,-z,max-page-size=16384
-Wl,-z,common-page-size=16384
Вот как обновить файлы конфигурации системы сборки:
ndk-build
Если вы используете ndk-build, обновите файл Android.mk, чтобы включить выравнивание ELF-файлов по границе 16 КБ:
LOCAL_LDFLAGS += -Wl,-z,max-page-size=16384 -Wl,-z,common-page-size=16384
CMake
Если вы используете CMake, обновите файл CMakeLists.txt, чтобы включить выравнивание ELF по границе 16 КБ:
target_link_options(${CMAKE_PROJECT_NAME} PRIVATE
"-Wl,-z,max-page-size=16384"
"-Wl,-z,common-page-size=16384"
)
Как исправить код и устранить проблемы во время выполнения
Даже если ваше приложение поддерживает страницы памяти размером 16 КБ, в нем могут возникать ошибки, если в коде предполагается, что на устройстве используются страницы памяти определенного размера. Чтобы избежать этого, выполните следующие действия:
Удалите все заданные в коде зависимости, которые ссылаются на константу
PAGE_SIZE, или экземпляры в логике кода, которые предполагают, что размер страницы памяти устройства составляет 4 КБ (4096).Вместо него используйте
getpagesize()илиsysconf(_SC_PAGESIZE).Найдите, где используются
mmap()и другие API, требующие аргументов с выравниванием по страницам, и при необходимости замените их альтернативными вариантами.
В некоторых случаях, если в приложении используется PAGE_SIZE как удобное значение, не связанное с размером страницы, это не приведет к сбою в режиме 16 КБ. Однако если это значение передается ядру с помощью mmap без MAP_FIXED, ядро все равно использует всю страницу, что приводит к потере памяти. Поэтому при включении режима 16 КБ в NDK r27 и более поздних версиях PAGE_SIZE не определяется.
Если ваше приложение использует PAGE_SIZE таким образом и никогда не передает это значение напрямую ядру, то вместо PAGE_SIZE создайте новую переменную с новым именем, чтобы отразить, что она используется для других целей и не отражает реальную страницу памяти.
Как оптимизировать собственные распределители памяти
В системах с размером страниц 16 КБ наименьшая единица физической памяти, которую выделяет операционная система, в четыре раза больше, чем в системах с размером страниц 4 КБ. Если специальный распределитель был разработан с учетом предположений о 4 КБ, он может разбрасывать небольшие объекты по нескольким страницам размером 16 КБ и без необходимости сохранять пустую память. Это может значительно увеличить использование физической памяти (RSS) и снизить эффективность сжатого файла подкачки (ZRAM).
Если ваш код управляет собственными пулами памяти, следуйте этим рекомендациям:
1. Не задавайте в коде пороговые значения в байтах для освобождения памяти
Многие распределители используют фиксированные ограничения в байтах, чтобы решить, когда возвращать память ОС с помощью madvise(MADV_DONTNEED) (например, возвращать память, только если активные объекты занимают менее 8 КБ).
В системе с размером страницы 16 КБ даже один активный объект размером 16 байт закрепляет всю страницу размером 16 КБ (что больше 8 КБ). В результате пороговое значение никогда не достигается, и распределитель никогда не возвращает окружающую неиспользуемую память ядру.
Что делать. Никогда не используйте заданные в коде константы байтов для эвристики освобождения страниц.
Динамически масштабировать пороговые значения выпуска во время выполнения на основе фактического размера страницы с помощью sysconf(_SC_PAGESIZE).
2. Сначала заполнять уже используемые страницы (плотное размещение)
Если распределитель выделяет память по принципу FIFO или циклического перебора, новые выделения распределяются по множеству частично заполненных страниц размером 16 КБ. Один объект на странице сохраняет все 16 КБ в физической ОЗУ.
Что делать. Всегда выделяйте новые объекты из наиболее полной (плотной) страницы или блока, прежде чем касаться пустых или малоиспользуемых страниц. Концентрация новых выделений на уже измененных страницах позволяет редко используемым страницам естественным образом освобождаться от активных объектов, чтобы вся страница размером 16 КБ могла быть передана ОС.
3. Выравнивайте пулы памяти по 16 КБ и не делайте их слишком большими
Многостраничные диапазоны, предназначенные для систем с размером страницы 4 КБ, могут содержать избыточный невысвобожденный объем памяти в ядрах с размером страницы 16 КБ. Кроме того, классы размеров, которые не делятся на 16 КБ без остатка, вызывают фрагментацию в конце каждой страницы.
Что нужно сделать:
- Убедитесь, что все пулы памяти, границы slab-аллокатора и выравнивания буфера кратны размеру страницы среды выполнения.
- Пересмотрите размеры многостраничных диапазонов для классов малых объектов, чтобы избежать выделения слишком больших блоков, которые задерживают неиспользуемую память.
4. Немедленно освобождать физическую память для больших буферов, сохраненных в кеше
Специальные распределители часто кешируют большие буферы (> 64 КБ) в пуле в памяти, чтобы их можно было использовать повторно без дополнительных затрат на системные вызовы mmap или munmap. Однако хранение этих грязных буферов в памяти приводит к потере мегабайтов физического ОЗУ в ожидании таймера вытеснения.
Что делать. Сохраните диапазон адресов виртуальной памяти, зарезервированный для быстрого повторного использования, но вызывайте madvise(..., MADV_DONTNEED) или madvise(..., MADV_FREE) сразу после возврата буфера в кеш. Операционная система сразу же освобождает физическую оперативную память, а ваше приложение может мгновенно повторно использовать виртуальный адрес без перераспределения.
5. Обнулять память при освобождении, а не при выделении для сжатия ZRAM
Android использует сжатый файл подкачки (ZRAM), чтобы хранить фоновые приложения в памяти. На устройствах с размером страниц 16 КБ, если на странице есть хотя бы один активный объект, вся страница размером 16 КБ остается резидентной или переносится в ZRAM. Оставшийся мусор (например, устаревшие указатели и строки) в ранее освобожденных частях страницы плохо сжимается.
Если ваш аллокатор обнуляет память (например, в целях безопасности или для обнуления выделенной памяти), рассмотрите возможность обнуления при освобождении (free()), а не при выделении:
- Закрепленные страницы требуют меньше ресурсов. Неиспользуемая память на частично заполненных страницах размером 16 КБ сжимается в ZRAM почти до нуля, поэтому закрепленные страницы не занимают физическое пространство подкачки.
- Минимальные накладные расходы на кеш. При вызове
free()память уже находится в кеше ЦП, что позволяет избежать дополнительных промахов кеша в дальнейшем.
Краткое описание рекомендаций
| Район | Рекомендация | Ожидаемый эффект |
|---|---|---|
| Пороговые значения для удаления | Динамически масштабируйте пороговые значения выпуска с помощью sysconf(_SC_PAGESIZE). |
Предотвращает постоянную блокировку логики выпуска. |
| Порядок распределения | Сначала выделяйте память на самых заполненных страницах или в самых заполненных областях. | Уменьшает объем резидентной памяти (RSS), упаковывая активные объекты вместе. |
| Размер диапазона | Выровняйте классы размеров по 16 КБ и избегайте слишком больших фрагментов. | Устраняет фрагментацию хвостовых страниц и уменьшает неиспользуемую память. |
| Кеш буфера | При кешировании больших буферов сразу вызывайте madvise(MADV_DONTNEED). |
Это позволяет избежать перегрузки ОЗУ и сохранить высокую скорость повторного использования виртуальной памяти. |
| Файл подкачки / ZRAM | Обнулять память при free(), а не при выделении. |
Улучшены коэффициенты сжатия ZRAM, поэтому закрепленные страницы занимают меньше места. |
Проверьте, поддерживают ли SDK страницы памяти размером 16 КБ
Многие SDK совместимы со страницами размером 16 КБ, особенно если вы создаете их самостоятельно или используете последние готовые версии. Однако некоторые готовые SDK или их версии несовместимы с размером страницы 16 КБ. Чтобы узнать, какую версию использовать, посетите сайт поставщика SDK.
Как протестировать приложение в среде с поддержкой страниц размером 16 КБ
После того как вы добавите в приложение поддержку устройств со страницами памяти размером 16 КБ, протестируйте его в среде с такими страницами, чтобы проверить, не возникло ли регрессий. Для этого выполните следующие действия:
Настройте Android 15 SDK или более поздней версии.
Настройте одну из следующих тестовых сред:
- Как настроить эмулятор Android с образом системы Android 15, поддерживающим страницы размером 16 КБ
- Как использовать Cuttlefish с размером страницы 16 КБ на ARM64
- Как запустить симулятор Cuttlefish с размером страницы 16 КБ на устройстве с архитектурой x86-64
- Как включить режим 16 КБ на устройстве в настройках для разработчиков
- Используйте Samsung Remote Test Lab на поддерживаемых устройствах с размером страницы 16 КБ.
Запустите тестовое устройство и выполните следующую команду, чтобы проверить, используется ли среда с поддержкой страниц размером 16 КБ:
adb shell getconf PAGE_SIZEКоманда должна возвращать значение
16384.Выполните следующую команду
zipalign, чтобы проверить, выровнено ли приложение по границе 16 КБ. APK_NAME – это название APK-файла приложения.zipalign -c -P 16 -v 4 APK_NAME.apkТщательно протестируйте приложение, уделяя особое внимание областям, которые могут быть затронуты изменением экземпляров кода, ссылающихся на определенные размеры страниц.
Как настроить эмулятор Android с образом системы на основе 16 КБ
Чтобы настроить среду с поддержкой страниц размером 16 КБ в эмуляторе Android, выполните следующие действия:
- В Android Studio нажмите Tools (Инструменты) > SDK Manager.
На вкладке SDK Platforms (Платформы SDK) выберите Show Package Details (Показать сведения о пакете), разверните раздел Android VanillaIceCream или более поздней версии и выберите один или оба следующих системных образа эмулятора в зависимости от того, какие виртуальные устройства вы хотите создать:
- Системный образ API Google Experimental 16 КБ Page Size ARM 64 v8a
- API Google Experimental 16 КБ Page Size Intel x86_64 Atom образ системы
Нажмите Apply (Применить) > OK, чтобы скачать выбранные образы системы.
Следуйте инструкциям по настройке виртуального устройства для Android 15. Когда вам будет предложено выбрать образ системы, выберите скачанный образ с поддержкой страниц размером 16 КБ. Если он не рекомендуется автоматически, вы можете найти образ системы с размером страницы 16 КБ на вкладке Other Images (Другие образы).
Запустите эмулятор
После того как вы настроите эмулятор Android и виртуальные устройства, запустите эмулятор из меню целевого устройства или из командной строки.
Включите режим 16 КБ на устройстве с помощью параметров разработчика.

Включите параметр разработчика «Загрузка с размером страницы 16 КБ» , чтобы загрузить устройство в режиме 16 КБ.
В версиях Android 15 QPR можно использовать режим разработчика , доступный на некоторых устройствах, чтобы загрузить устройство в режиме 16 КБ и выполнить тестирование на устройстве. Перед использованием режима разработчика перейдите в Настройки > Система > Обновления ПО и примените все доступные обновления.
Данная опция для разработчиков доступна на следующих устройствах:
Pixel 8 и 8 Pro (с Android 15 QPR1 или выше)
Pixel 8a (с Android 15 QPR1 или выше)
Pixel 9, 9 Pro и 9 Pro XL (с Android 15 QPR2 или выше)
Pixel 9a (с Android 16 или выше)
Режим совместимости с размером страницы 16 КБ
Предупреждение в режиме совместимости с размером страницы
Вариант "Обратная совместимость с размером страницы 16 КБ" доступен, если на устройстве используется ядро с размером страницы 16 КБ. Менеджер пакетов запускает приложение в режиме обратной совместимости со страницами памяти размером 16 КБ, если выполняются следующие условия:
- Если в приложении есть файлы ELF (с расширением
.so) с выравниванием сегмента LOAD, равным 4 КБ. - Если в ZIP-архиве APK-файла есть несжатые ELF-файлы, выровненные по границе 4 КБ.
Если менеджер пакетов включил для приложения режим обратной совместимости с 16 КБ, при первом запуске приложения появится предупреждение о том, что оно работает в этом режиме.
Режим обратной совместимости с размером страницы 16 КБ позволяет некоторым приложениям работать, но для обеспечения надежности и стабильности приложения должны быть выровнены по размеру 16 КБ.
На странице с информацией о приложении в разделе Расширенные включите или отключите параметр Запускать приложение в режиме совместимости с размером страницы, чтобы включить или отключить режим обратной совместимости с размером страницы 16 КБ для определенного приложения. Этот параметр виден, только если на устройстве установлен размер страницы 16 КБ.
Настройка режима совместимости с размером страницы
Чтобы принудительно включить обратную совместимость со страницами памяти размером 16 КБ для всех приложений на устройстве, выполните следующую команду:
adb shell setprop bionic.linker.16kb.app_compat.enabled true
adb shell setprop pm.16kb.app_compat.disabled false
Чтобы принудительно отключить обратную совместимость 16 КБ для всех приложений на устройстве, выполните следующую команду:
adb shell setprop bionic.linker.16kb.app_compat.enabled false
adb shell setprop pm.16kb.app_compat.disabled true
В Android 17 вы также можете принудительно отключить обратную совместимость с 16 КБ для каждого приложения и заставить любой несовместимый двоичный файл немедленно прервать работу:
adb shell setprop bionic.linker.16kb.app_compat.enabled fatal
adb shell setprop pm.16kb.app_compat.disabled true
Чтобы включить или отключить режим обратной совместимости для определенного приложения, задайте для свойства android:pageSizeCompat значение enabled или disabled в файле AndroidManifest.xml. Если это свойство задано, при запуске приложения не будут показываться предупреждения о режиме обратной совместимости.