一、背景
经常出现这样的现象,Android设备在开机后,就发生了lowmemorykiller,特别是在刷机后首次开机。
使用命令dumpsys meminfo 查看,发现PSS通常比较低,而大量的内存被cached kernel占用。
Total RAM: 6,120,920K (status moderate)
Free RAM: 2,181,435K ( 71,559K cached pss + 1,795,412K cached kernel + 314,464K free)
Used RAM: 2,883,076K (2,122,704K used pss + 760,372K kernel)
二、回收cached kernel
cached kernel很多是因为android在开机后产生了大量的文件缓存。这些文件缓存在开机后并不会立即回收。如果想立即回收,可以通过命令:
sysctl -w vm.drop_caches=1
来触发drop_caches. 或者:
echo 1 /proc/sys/vm/drop_caches
参数1可以改成2,3,对应不同的回收级别。
但是android默认并没有配置drop_caches,也没有场景触发drop caches。 这就需要客制化。
三、客制化drop caches
以下是一种客制化方案参考。思路是在init.rc 里面加上drop caches脚本,在JAVA或者native层通过修改property触发回收。
1. 在init.rc里面加上脚本
on property:persist.vendor.gwm.config.drop_caches=*
write /dev/kmsg "[ryan] noch set persist.vendor.fiill.config.drop_caches"
write /proc/sys/vm/drop_caches ${persist.vendor.fiill.config.drop_caches}
2. 配置init.rc的sepolicy权限
init.te
allow vendor_init vendor_prop:file {read open getattr map};
allow vendor_init proc_drop_caches:file {read open getattr map write};
3. native层示例代码,本例是仅在第一次开机才尝试回收
char value[255] = {0};
property_get("persist.sys.system.bootcount", value, NULL);
if(atoi(value) == 1) {
int ret = -1;
ret = property_set("persist.vendor.fiill.config.drop_caches", "1");
ALOGI("%s: ryan set persist.vendor.fiill.config.drop_caches=1, ret=%d", __func__, ret);
}
4. native进程加上sepolicy权限
set_prop(my_hal_process, system_prop)
get_prop(my_hal_process, system_prop)
set_prop(my_hal_process, vendor_prop)
get_prop(my_hal_process, vendor_prop)
allow my_hal_process vendor_prop:file {read open getattr map};
5. java层使用也类似,例如在SystemServer.java里面找个合适位置加上:
int bootCount = SystemProperties.getInt("persist.sys.system.bootcount", 0);
if(bootCount == 1){
SystemProperties.set("persist.vendor.fiill.config.drop_caches", "1");
Slog.w(TAG, "=======hxq===222===>>>>>>> " + bootCount +
" [" + SystemProperties.getInt("persist.vendor.fiill.config.drop_caches", -1)+"]");
}