Телефон вытесняет неактивные приложения из оперативной памяти, несмотря на много свободной памяти

Телефон (Jiayu G4S) работает под управлением Android 4.4.2, 2 Гб оперативной памяти, стоковая прошивка jiayu.es (ядро 3.4.67)

Стоковая конфигурация также устанавливает некоторый своп в zram, я его отключил, похоже, не имеет значения.

Диспетчер задач показывает в любое время не менее 0,92 Гб свободного места или больше. Он показывает не более 12-13 кешированных неактивных приложений, которые все еще находятся в оперативной памяти, немного больше, если лимит процессов вручную установлен на высокое значение (просто для удовольствия я выбираю 100).

Согласно dumpsys meminfo, вот как это выглядит сейчас:

Total RAM: 2016644 kB
 Free RAM: 883420 kB (230000 cached pss + 131652 cached + 521768 free)
 Used RAM: 852001 kB (805401 used pss + 1684 buffers + 8972 shmem + 35944 slab)
 Lost RAM: 281223 kB
     ZRAM: 4 kB physical used for 0 kB in swap (0 kB total swap)
   Tuning: 256 (large 512), oom 122880 kB, restore limit 40960 kB (high-end-gfx)

И тем не менее, часто используемые приложения периодически выбрасываются из памяти (показаны в диспетчере задач с выделенным 0.00b), что приводит к небольшой задержке при следующем запуске.

параметры oomkiller кажутся вменяемыми

shell@G4:/ $ cat /sys/module/lowmemorykiller/parameters/minfree                
12288,15360,18432,21504,24576,30720

Почему часто используемые программы выкидываются, несмотря на всю эту свободную память? Можно ли что-нибудь настроить (у меня есть root-доступ)?

Ответы (1)

А теперь отвечу себе. Глядя на исходники Android 4.4.2 (KOT39H), в ProcessList.java мы определили максимальное количество кэшированных приложений, установленное на произвольное значение 24:

static final int MAX_CACHED_APPS = 24;

Далее это значение разбивается с помощью функции calculateEmptyProcessLimit следующим образом: 2/3 идет на лимит пустого процесса, а 1/3 идет на лимит кэшированного процесса.

Итак, теперь у нас есть произвольное ограничение в 16 для пустых и 8 для кешированных процессов. (Но купите телефон с 3 Гб оперативной памяти, чтобы посмотреть, сколько у вас останется неиспользуемой памяти)

В стандартном Android единственный способ изменить это ограничение — во время выполнения с помощью setProcessLimit(), для чего требуется рутированный телефон, приложение, установленное вручную в /system/priv-app, и предоставленное разрешение SET_PROCESS_LIMIT.

(В СМ11 например его тоже можно выставить в build.prop, но этого кода нет в стоковой 4.4.2)

К счастью, на гитхабе уже есть такое приложение под названием SetAndroidProcessLimit, которое при правильной установке работает (спасибо автору)

Теперь у меня есть 20 кешированных приложений в оперативной памяти, это почти все приложения, которые я часто использую, и любое из них запускается мгновенно, без задержки.


Я также понял, как изменить MAX_CACHED_APPS прямо в /system/framework/services.jar.

  • скачать банку на свой компьютер, распаковать банку
  • декомпилировать class.dex с помощью baksmali (или через apktool)
  • изменить в ProcessList.smali и в ActivityManagerService.smali - поскольку это байт-код, вы должны заменить не только объявление MAX_CACHED_APPS, но и каждое его появление новым желаемым значением
  • перекомпилировать классы.dex
  • переупаковать банку
  • скачать на телефон, заменив оригинальный jar (нужно перемонтировать rw /system)
  • перезагрузить телефон; мой автоматически регенерирует кеш dalvik