Процесс устранения нехватки памяти 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 |