Демон-убийца нехватки памяти

Процесс устранения нехватки памяти Android ( lmkd ) отслеживает состояние памяти работающей системы Android и реагирует на высокую нехватку памяти, убивая наименее важные процессы, чтобы поддерживать производительность системы на приемлемом уровне.

О нехватке памяти

Система Android, выполняющая несколько процессов параллельно, может столкнуться с ситуациями, когда системная память исчерпана, а процессы, требующие большего объема памяти, испытывают заметные задержки. Недостаток памяти — состояние, при котором системе не хватает памяти, — требует, чтобы Android освободил память (чтобы облегчить нагрузку) путем регулирования или уничтожения неважных процессов, запроса процессов на освобождение некритических кэшированных ресурсов и т. д.

Исторически сложилось так, что Android отслеживал нехватку системной памяти с помощью встроенного в ядро ​​драйвера LMK — жесткого механизма, зависящего от жестко запрограммированных значений. Начиная с ядра 4.12, драйвер LMK удален из вышестоящего ядра, а пользовательское пространство lmkd выполняет задачи мониторинга памяти и уничтожения процессов.

Информация о стойле давления

Android 10 и более поздних версий поддерживают новый режим lmkd , который использует мониторы информации о давлении ядра (PSI) для обнаружения нехватки памяти. Набор патчей PSI в исходном ядре (перенесенный в ядра 4.9 и 4.14) измеряет время, на которое задачи задерживаются из-за нехватки памяти. Поскольку эти задержки напрямую влияю�� на взаимодействие с пользователем, они представляют собой удобный показатель для определения серьезности нехватки памяти. Вышестоящее ядро ​​также включает в себя мониторы PSI, которые позволяют процессам привилегированного пользовательского пространства (таким как lmkd ) указывать пороговые значения для этих задержек и подписываться на события ядра при нарушении порогового значения.

Мониторы PSI и сигналы vmpressure

Поскольку сигналы vmpressure (сгенерированные ядром для обнаружения нехватки памяти и используемые lmkd ) часто содержат множество ложных срабатываний, lmkd должен выполнить фильтрацию, чтобы определить, находится ли память под реальной нагрузкой. Это приводит к ненужным пробуждениям lmkd и использованию дополнительных вычислительных ресурсов. Использование мониторов PSI обеспечивает более точное определение нехватки памяти и минимизирует накладные расходы на фильтрацию.

Используйте мониторы PSI

Чтобы использовать мониторы PSI вместо событий vmpressure , настройте свойство ro.lmk.use_psi . По умолчанию установлено значение true , что делает мониторинг PSI механизмом обнаружения нехватки памяти по умолчанию для lmkd . Поскольку мониторам PSI требуется поддержка ядра, ядро ​​должно включать исправления обратного порта PSI и быть скомпилировано с включенной поддержкой PSI ( CONFIG_PSI=y ).

Недостатки встроенного драйвера LMK

Android прекращает поддержку драйвера LMK из-за ряда проблем, в том числе:

  • Устройства с малым объемом оперативной памяти нужно было тщательно настраивать, и даже в этом случае они плохо работали при рабочих нагрузках с большим активным кэшем страниц, поддерживаемым файлами. Плохая игра привела к избиению и отсутствию убийств.
  • Драйвер ядра LMK полагался на ограничения свободной памяти без масштабирования в зависимости от нехватки памяти.
  • Из-за жесткости конструкции партнеры часто настраивали драйвер так, чтобы он работал на их устройствах.
  • Драйвер LMK подключался к API-интерфейсу сжатия плит, который не был предназначен для тяжелых операций, таких как поиск целей и их уничтожение, что замедляло процесс vmscan .

Пользовательское пространство lmkd

Пользовательское пространство lmkd реализует ту же функциональность, что и встроенный в ядро ​​драйвер, но использует существующие механизмы ядра для обнаружения и оценки нехватки памяти. Такие механизмы включают использование генерируемых ядром событий vmpressure или мониторов информации о остановке давления (PSI) для получения уведомлений об уровнях нехватки памяти, а также использование функций контрольной группы памяти для ограничения ресурсов памяти, выделяемых каждому процессу, в зависимости от важности процесса.

Используйте пользовательское пространство lmkd в Android 10

В Android 9 и более поздних версиях пользовательское пространство lmkd активируется, если встроенный в ядро ​​драйвер LMK не обнаружен. Поскольку в пользовательском пространстве lmkd требуется поддержка ядром контрольных групп памяти, ядро ​​нео��ходимо скомпилировать со следующими параметрами конфигурации:

CONFIG_ANDROID_LOW_MEMORY_KILLER=n
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y

Стратегии убийства

Пользовательское пространство lmkd поддерживает стратегии уничтожения, основанные на событиях vmpressure или мониторах PSI, их серьезности и других подсказках, таких как использование подкачки. Стратегии уничтожения различаются для устройств с низким объемом памяти и высокопроизводительных устройств:

  • На устройствах с малым объемом памяти система должна допускать более высокий уровень нехватки памяти в обычном режиме работы.
  • На высокопроизводительных устройствах нехватку памяти следует рассматривать как ненормальную ситуацию и устранять ее до того, как она повлияет на общую производительность.

Вы можете настроить стратегию уничтожения, используя свойство ro.config.low_ram . Подробности см. в разделе Конфигурация с малым объемом оперативной памяти .

Пользовательское пространство lmkd также поддерживает устаревший режим, в котор��м он принимает решения об уничтожении, используя те же стратегии, что и встроенный в ядро ​​драйвер LMK (то есть пороговые значения свободной памяти и файлового кэша). Чтобы включить устаревший режим, установите для свойства ro.lmk.use_minfree_levels значение true .

Настроить лмкд

Настройте lmkd для конкретного устройства, используя следующие свойства.

Свойство Использовать По умолчанию
ro.config.low_ram Укажите, является ли устройство устройством с низким объемом оперативной памяти или высокопроизводительным. false
ro.lmk.use_psi Используйте мониторы PSI (вместо событий vmpressure ). true
ro.lmk.use_minfree_levels Используйте пороговые значения свободной памяти и файлового кэша для принятия решений об уничтожении процесса (то есть соблюдайте функциональность встроенного драйвера LMK). false
ro.lmk.low Минимальный показатель oom_adj для процессов, которые могут быть завершены при низком уровне vmpressure . 1001
(неполноценный)
ro.lmk.medium Минимальный показатель oom_adj для процессов, которые могут быть завершены на среднем уровне vmpressure . 800
(кэшированные или несущественные службы)
ro.lmk.critical Минимальный показатель oom_adj для процессов, которые могут быть завершены при критическом уровне vmpressure . 0
(любой процесс)
ro.lmk.critical_upgrade Включите обновление до критического уровня. false
ro.lmk.upgrade_pressure Максимальное mem_pressure при котором уровень повышается, поскольку система слишком много подкачивает. 100
(неполноценный)
ro.lmk.downgrade_pressure Минимальное mem_pressure , при котором событие vmpressure игнорируется, поскольку все еще доступно достаточно свободной памяти. 100
(неполноценный)
ro.lmk.kill_heaviest_task Уничтожьте самую тяжелую подходящую задачу (лучшее решение) по сравнению с любой подходящей задачей (быстрое решение). true
ro.lmk.kill_timeout_ms Продолжительность в миллисекундах после убийства, когда дополнительные убийства выполняться не будут. 0
(неполноценный)
ro.lmk.debug Включите журналы отладки lmkd . false

Пример конфигурации устройства:

PRODUCT_PROPERTY_OVERRIDES += \
    ro.lmk.low=1001 \
    ro.lmk.medium=800 \
    ro.lmk.critical=0 \
    ro.lmk.critical_upgrade=false \
    ro.lmk.upgrade_pressure=100 \
    ro.lmk.downgrade_pressure=100 \
    ro.lmk.kill_heaviest_task=true

Пользовательское пространство lmkd в Android 11

Android 11 улучшает lmkd , вводя новую стратегию убийства. Стратегия уничтожения использует механизм PSI для обнаружения нехватки памяти, представленный в Android 10. lmkd в Android 11 учитывает уровни использования ресурсов памяти и их перегрузку, чтобы предотвратить нехватку памяти и снижение производительности. Эта стратегия уничтожения заменяет предыдущие стратегии и может использоваться как на высокопроизводительных устройствах, так и на устройствах с низким объемом оперативной памяти (Android Go).

Требования ядра

Для устройств Android 11 lmkd требует следующих функций ядра:

  • Включите патчи PSI и включите PSI (бэкпорты доступны в общих ядрах Android 4.9, 4.14 и 4.19).
  • Включите исправления поддержки PIDFD (обратные порты доступны в общих ядрах Android 4.9, 4.14 и 4.19).
  • Для устройств с низким объемом оперативной памяти включите контрольные группы памяти.

Ядро должно быть скомпилировано со следующими настройками конфигурации:

CONFIG_PSI=y

Настройте lmkd в Android 11

Стратегия уничтожения памяти в Android 11 поддерживает ручки настройки и настройки по умолчанию, перечисленные ниже. Эти функции работают как на высокопроизводительных устройствах, так и на устройствах с низким объемом оперативной памяти.

Свойство Использовать По умолчанию
Высокая производительность Низкая оперативная память
ro.lmk.psi_partial_stall_ms Частичный порог задержки PSI в миллисекундах для запуска уведомления о нехватке памяти. Если устройство получает уведомления о нехватке памяти слишком поздно, уменьшите это значение, чтобы активировать более ранние уведомления. Если уведомления о нехватке памяти срабатывают без необходимости, увеличьте это значение, чтобы сделать устройство менее чувствительным к шуму. 70 200
ro.lmk.psi_complete_stall_ms Полный порог остановки PSI в миллисекундах для запуска уведомлений о критической памяти. Если устройство получает уведомления о критическом нехватке памяти слишком поздно, уменьшите это значение, чтобы активировать более ранние уведомления. Если уведомления о критическом нехватке памяти срабатывают без необходимости, увеличьте это значение, чтобы сделать устройство менее чувствительным к шуму. 700
ro.lmk.thrashing_limit Максимальное количество сбоев рабочего набора в процентах от общего размера файлового кэша страниц. Сбои рабочего набора выше этого значения означают, что система перегружает свой кэш страниц. Если нехватка памяти влияет на производительность устройства, ��меньшите значение, чтобы ограничить перебои. Если производительность устройства без необходимости снижается из-за сбоев, увеличьте значение, чтобы обеспечить более высокий уровень сбоев. 100 30
ro.lmk.thrashing_limit_decay Снижение порога сбоя выражается в процентах от исходного порога, используемого для понижения порога, когда система не восстанавливается, даже после уничтожения. Если продолжительное избиение приводит к ненужным убийствам, уменьшите значение. Если реакция на постоянные избиения после убийства слишком медленная, увеличьте значение. 10 50
ro.lmk.swap_util_max Максимальный объем подкачиваемой памяти в процентах от общего объема подкачиваемой памяти. Когда объем подкачиваемой памяти превышает этот предел, это означает, что система заменила большую часть своей подкачиваемой памяти и все еще находится под давлением. Это может произойти, когда неподкачиваемые выделения создают нагрузку на память, которую невозможно уменьшить путем замены, поскольку большая часть подкачиваемой памяти уже выгружена. Значение по умолчанию — 100, что фактически отключает эту проверку. Если на производительность устройства влияет нехватка памяти, когда использование подкачки высокое, а уровень свободной подкачки не падает до ro.lmk.swap_free_low_percentage , уменьшите значение, чтобы ограничить использование подкач��и. 100 100

Следующие старые ручки настройки также работают с новой стратегией убийства.

Свойство Использовать По умолчанию
Высокая производительность Низкая оперативная память
ro.lmk.swap_free_low_percentage Уровень свободного подкачки в процентах от общего пространства подкачки. `lmkd` использует это значение в качестве порога, когда следует считать, что в системе не хватает места подкачки. Если lmkd завершает работу, когда в подкачке слишком много места, уменьшите процент. Если убийства `lmkd` происходят слишком поздно и позволяют совершать убийства OOM, увеличьте процент. 20 10
ro.lmk.debug Это активирует журналы отладки lmkd. Включите отладку во время настройки. false