
Разработав инструмент для визуализации RAM и zRAM в Android, я обнаружила, что в телефонах происходит активная конкуренция за ресурсы. И если процессу понадобятся ресурсы, которые уже заняты кем-то другим, он отберет их, что может привести к критическим ситуациям и конфликтам оборудования.
Пользовались ли вы когда-нибудь такими утилитами как htop, top, vmstat? Если у вас вообще установлен Linux, то скорее всего да. И они действительно хорошо показывают статистику использования ресурсов в ОС. Я исследовала операционные системы, и мне не хватало понимания того, как реально выглядит физическое адресное пространство: какие конкретно адреса заняты, какие свободны, что происходит, если процессы запрашивают одни и те же адреса, как часто это происходит.
Была гипотеза, что в Android (и в Linux), возникает активная конкуренция за ресурсы. Спойлер из названия статьи: она подтвердилась.
Я разработала приложение, визуализирующее размещение процессов в памяти в телефонах с операционной системой Android. Данные считываются для каждой страницы памяти для выбранного процесса. Эти данные также можно дополнительно обработать. Разработанный инструмент позволяет пользователю исследовать как оперативную память, так и ZRAM, отображать полученную информацию в графическом виде. Пользователь может выбрать процессы из дерева cgroups.
Главное окно приложения выглядит следующим образом. Далее будет рассмотрена именно карта памяти, которая отображается по центру.

Немного теории
Управление памятью в Android является частью функциональности ядра Linux. Ядро имеет полный доступ к системной памяти и позволяет процессам безопасно обращаться к этой памяти по мере необходимости. Приложениям требуется много ресурсов, и поэтому диагностика, анализ и отладка используются для оптимального выделения ресурсов для приложений. Понимание динамики перераспределения памяти может дать гораздо более четкую картину системы. Между тем, мобильные операционные системы имеют больше ограничений, связанных с аппаратным и программным обеспечением, по сравнению с настольными операционными системами.
Управление памятью в ОС Android организовано с помощью страниц размером 4 КБ. Ядро отслеживает состояние каждой страницы физической памяти, представленной в системе.
Я исследовала методы управления памятью в Android и Linux и сравнила доступные инструменты для проверки и мониторинга памяти. Нет инструментов, которые могли бы визуализировать картину. А также трудно интерпретировать числа, поэтому я ввела качественный индикатор и отобразила карту памяти постранично.
apagescan собирает информацию о распределении памяти между несколькими процессами, затем создает снимки памяти и фиксирует динамические изменения памяти. apagescan работает с procFS для чтения любого количества страниц в оперативной памяти, предоставляя информацию о каждой странице, включая флаги present/swapped/dirty и anon/not anon.
Каждая страница может находиться в одном из следующих состояний:
Present / not Present: Текущая страница отображается на страницу в физической памяти. Если страница не present, ее можно свапнуть (переместить) на диск.
Dirty / Clean: Грязные (dirty) страницы - это страницы, которые были изменены, поскольку они были выгружены в физическую память из дисковой памяти и ожидают записи обратно на диск. Чистые (clean) страницы - это страницы, которые не были модифицированы процессом.
Named / Anonymous: Именованные (named) чистые страницы могут быть восстановлены из специального файла. Анонимные (anonymous) страницы поддерживаются разделом подкачки (swap) или физической памятью. Анонимные чистые страницы могут быть восстановлены из /dev/zero.
Также пользователи могут выбирать процессы из cgroups для проверки. cgroups это механизм для группировки процессов на уровне ядра.
Полученные снимки памяти
На Nexus 5 были запущены три приложения, которые использовались в общей сложности в течение двух минут, в то время как apagescan собирал данные с задержкой 0 сек. между измерениями. Было сделано 60 снимков физической памяти. Каждый квадрат (точка) на рисунке это страница в памяти телефона. Черной жирной линией внизу рисунков отделен раздел подкачки.
В эксперименте использовались приложения камеры (синий цвет - 5837 PID), браузера (цвет фуксии - 5307 PID) и галереи (зеленый цвет - 5390 PID). На рис. ниже представлено начальное состояние памяти, когда использовалось приложение браузера, а другие приложения находились в фоновом режиме. Большая часть оперативной памяти занята браузером и гораздо меньше - камерой и галереей. Также отсутствуют страницы в области подкачки.

Во время работы браузера произошли некоторые изменения в отображении памяти, но они стали заметны только тогда, когда приложение браузера перешло в фоновый режим и было выбрано приложение камеры (см. рис. 2). Некоторые страницы были вытеснены страницами камеры, но большинство из них остались на своих местах, а страницы камеры просто заняли свободное место.

На рис. 3-4 показана «конкуренция» между приложениями камеры и галереи (красная область) и процесс вытеснения страниц, когда приложение переходит в фоновый режим (синяя область). То есть на рисунках видно, как разные приложения обращаются к одним и тем же участкам памяти (точки на графиках перекрывают друг друга). И тестирование различных приложений, позволило мне увидеть, что конкуренция за ресурсы происходит достаточно часто. Особенно, если ресурсов не очень много, что, конечно, справедливо для мобильных телефонов.


Выводы
Знание об активной конкуренции за память в Android, может пригодиться как при разработке мобильных приложений, так и областей, связанных с планированием ресурсов в ОС Android (и Linux). Когда один процесс запрашивает ресурсы, которые уже заняты кем-то другим, первый просто отберет их. Это может привести к бесконечному переключению контекста во время нехватки ресурсов, а также к критическим ситуациям и конфликтам оборудования. При этом выявление того, как приложения борются за ресурсы, позволяет оптимизировать систему целиком.