Платформа Android работает по принципу, что свободная память — это потраченная впустую память. Она постоянно стремится использовать всю доступную память. Например, система сохраняет приложения в памяти после их закрытия, чтобы пользователь мог быстро вернуться к ним. По этой причине устройства Android часто работают с очень небольшим объемом свободной памяти. Управление памятью имеет решающее значение для правильного распределения памяти между важными системными процессами и множеством пользовательских приложений.
На этой странице рассматриваются основные принципы распределения памяти в Android для системы и пользовательских приложений. Также объясняется, как операционная система реагирует на нехватку памяти.
Типы памяти
В устройствах Android используются три типа памяти: оперативная память (RAM), zRAM и хранилище. Следует отметить, что как центральный, так и графический процессоры обращаются к одной и той же оперативной памяти.
Рисунок 1. Типы памяти — ОЗУ, zRAM и хранилище.
Оперативная память (RAM) — это самый быстрый тип памяти, но обычно её объём ограничен. В высокопроизводительных устройствах, как правило, используются самые большие объёмы оперативной памяти.
zRAM — это раздел оперативной памяти, используемый в качестве пространства подкачки. Все данные сжимаются при помещении в zRAM, а затем распаковываются при копировании из zRAM. Размер этой части оперативной памяти увеличивается или уменьшается по мере перемещения страниц в zRAM или извлечения их из нее. Производители устройств могут устанавливать максимальный размер.
Память содержит все постоянные данные, такие как файловая система и включенный объектный код для всех приложений, библиотек и платформы. Память имеет гораздо больший объем, чем два других типа памяти. В Android память не используется в качестве пространства подкачки, как в других реализациях Linux, поскольку частая запись может привести к износу этой памяти и сократить срок службы носителя информации.
Страницы памяти
Оперативная память разбита на страницы . Как правило, каждая страница содержит 4 КБ памяти.
Информационные страницы делятся на свободные и используемые . Свободные страницы — это неиспользуемая оперативная память. Используемые страницы — это оперативная память, которую система активно использует, и они группируются по следующим категориям:
- Кэшированная память: память, поддерживаемая файлом на хранилище (например, кодом или файлами, отображаемыми в память). Существует два типа кэшированной памяти:
- Частный: принадлежит одному процессу и не используется совместно.
- Очищено: Неизмененная копия файла в хранилище, которую можно удалить с помощью
kswapdдля увеличения объема свободной памяти. - Dirty: Модифицированная копия файла на хранилище; может быть перемещена в zRAM или сжата в zRAM программой
kswapdдля увеличения объема свободной памяти.
- Очищено: Неизмененная копия файла в хранилище, которую можно удалить с помощью
- Общий: используется несколькими процессами.
- Очищено: Неизмененная копия файла на хранилище, может быть удалена с помощью
kswapdдля увеличения объема свободной памяти. - Dirty: Измененная копия файла в хранилище; позволяет записывать изменения обратно в файл в хранилище для увеличения свободной памяти с помощью
kswapdили явно используяmsync()илиmunmap()
- Очищено: Неизмененная копия файла на хранилище, может быть удалена с помощью
- Частный: принадлежит одному процессу и не используется совместно.
- Анонимно: Память не поддерживается файлом в хранилище (например, выделена функцией
mmap()с установленным флагомMAP_ANONYMOUS).- Dirty: Может быть перемещен/сжат в zRAM с помощью
kswapdдля увеличения свободной памяти.
- Dirty: Может быть перемещен/сжат в zRAM с помощью
Соотношение свободных и используемых страниц памяти меняется со временем, поскольку система активно управляет оперативной памятью. Представленные в этом разделе концепции являются ключевыми для управления ситуациями с нехваткой памяти. В следующем разделе этого документа они объясняются более подробно.
Низкий уровень управления памятью
В Android существует два основных механизма для решения проблем, связанных с нехваткой памяти: демон подкачки ядра и механизм завершения процесса при низкой загрузке памяти.
демон подкачки ядра
Демон подкачки ядра ( kswapd ) является частью ядра Linux и преобразует используемую память в свободную. Демон активируется, когда объем свободной памяти на устройстве становится низким. Ядро Linux поддерживает нижний и верхний пороги свободной памяти. Когда объем свободной памяти падает ниже нижнего порога, kswapd начинает освобождать память. Как только объем свободной памяти достигает верхнего порога, kswapd прекращает освобождение памяти.
kswapd может восстанавливать чистые страницы, удаляя их, поскольку они хранятся в памяти и не были изменены. Если процесс пытается обратиться к удаленной чистой странице, система копирует страницу из памяти в оперативную память. Эта операция известна как страничная адресация по запросу .
Рисунок 2. Чистая страница, сохраненная в хранилище, удалена.
kswapd может перемещать кэшированные частные и анонимные измененные страницы в zRAM, где они сжимаются. Это освобождает доступную память в ОЗУ (свободные страницы). Если процесс пытается обратиться к измененной странице в zRAM, страница распаковывается и перемещается обратно в ОЗУ. Если процесс, связанный со сжатой страницей, завершается, то страница удаляется из zRAM.
Если объем свободной памяти падает ниже определенного порога, система начинает завершать процессы.
Рисунок 3. Загрязненная страница перемещена в zRAM и сжата.
Убийца с плохой памятью
Во многих случаях kswapd не может освободить достаточно памяти для системы. В этом случае система использует onTrimMemory() , чтобы уведомить приложение о нехватке памяти и необходимости уменьшить её выделение. Если этого недостаточно, ядро начинает завершать процессы для освобождения памяти. Для этого используется механизм завершения процессов при нехватке памяти (LMK).
Для определения того, какой процесс завершить, LMK использует показатель «нехватки памяти», называемый oom_adj_score , для определения приоритета запущенных процессов. Процессы с высоким показателем завершаются первыми. Фоновые приложения завершаются первыми, а системные процессы — последними. В следующей таблице перечислены категории оценки LMK от высокой к низкой. Элементы с наивысшим показателем (в первой строке) будут завершены первыми:
Рисунок 4. Процессы Android, с высокими показателями вверху и низкими показателями внизу.
Ниже приведены описания различных категорий, представленных в таблице выше:
Фоновые приложения: приложения, которые запускались ранее и в данный момент неактивны. LMK сначала завершит работу фоновых приложений, начиная с того, у которого самый высокий
oom_adj_score.Предыдущее приложение: приложение, которое использовалось в фоновом режиме совсем недавно. Предыдущее приложение имеет более высокий приоритет (более низкий балл), чем фоновые приложения, поскольку вероятность того, что пользователь переключится на него, выше, чем на одно из фоновых приложений.
Приложение «Домой»: это приложение-запускатель. Закрытие этого приложения приведет к исчезновению обоев.
Сервисы: Сервисы запускаются приложениями и могут включать синхронизацию или загрузку данных в облако.
Приложения, воспринимаемые пользователем: приложения, не находящиеся на переднем плане, но тем или иным образом воспринимаемые пользователем, например, поисковый процесс, отображающий небольшой пользовательский интерфейс, или прослушивание музыки.
Приложение на переднем плане: приложение, которое используется в данный момент. Завершение работы приложения на переднем плане выглядит как сбой приложения, что может указывать пользователю на неполадки в устройстве.
Постоянные (сервисы): это основные сервисы устройства, такие как телефония и Wi-Fi.
Система: Системные процессы. При завершении этих процессов телефон может выглядеть так, будто он перезагружается.
Нативные процессы: процессы очень низкого уровня, используемые системой (например,
kswapd).
Производители устройств могут изменить поведение LMK.
Расчет объема используемой памяти
Ядро отслеживает все страницы памяти в системе.
Рисунок 5. Страницы, используемые различными процессами.
При определении объема памяти, используемой приложением, система должна учитывать общие страницы памяти. Приложения, обращающиеся к одной и той же службе или библиотеке, будут совместно использовать страницы памяти. Например, Google Play Services и игровое приложение могут совместно использовать службу определения местоположения. Это затрудняет определение того, какой объем памяти принадлежит службе в целом, а какой — каждому приложению.
Рисунок 6. Страницы, используемые двумя приложениями (посередине).
Для определения объема памяти, используемой приложением, можно использовать любую из следующих метрик:
- Размер набора резидентных страниц (RSS): количество общих и необщих страниц, используемых приложением.
- Размер пропорционального набора (PSS): количество неразделяемых страниц, используемых приложением, и равномерное распределение разделяемых страниц (например, если три процесса используют 3 МБ, каждый процесс получает 1 МБ в рамках PSS).
- Уникальный размер набора страниц (USS): количество страниц, не используемых приложением совместно (совместно используемые страницы не учитываются).
PSS полезен для операционной системы, когда ей нужно знать, сколько памяти используется всеми процессами, поскольку страницы не учитываются несколько раз. Расчет PSS занимает много времени, потому что системе необходимо определить, какие страницы используются совместно и сколькими процессами. RSS не различает совместно используемые и несовместно используемые страницы (что делает его расчет быстрее) и лучше подходит для отслеживания изменений в распределении памяти.
Дополнительные ресурсы
- Обзор управления памятью
- Процессы и жизненный цикл приложений
- Анализ использования памяти Android — презентация Google I/O
- Память и игры для Android — презентация на Google I/O
- Демон завершения процесса при нехватке памяти в Android
Рекомендуем вам
- Примечание: текст ссылки отображается, когда JavaScript отключен.
- время запуска приложения