Демон-убийца с низким объемом памяти

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

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

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

Исторически сложилось так, что Android отслеживал нехватку системной памяти с помощью встроенного в ядро ​​драйвера low memory killer (LMK), жесткого механизма, который зависит от жестко заданных значений. Начиная с ядром 4.12, драйвер ЛОК удаляются из верхнего ядра и пользовательского пространство lmkd мониторинга памяти выполняет и технологические задачи убийства.

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

Android 10 и более поздние версии поддерживают новый lmkd режим , который использует Kernel стойла давления информации (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 полагался на ограничения свободной памяти без масштабирования, основанного на нехватке памяти.
  • Из-за жесткости конструкции партнеры часто настраивали драйвер так, чтобы он работал на их устройствах.
  • Водитель ЛМК зацепили в горбыль Shrinker API, который не был разработан для тяжелых операций , таких как поиск целей и убивая их, которые замедлили vmscan процесс.

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

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

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

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

CONFIG_ANDROID_LOW_MEMORY_KILLER=n
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y

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

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

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

Вы можете настроить стратегию убийств с использованием ro.config.low_ram свойства (подробнее см Низкой Конфигурации RAM ).

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

Настройка lmkd

Настройка 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