Android-属性

属性是Android系统的一大特色,它用来进行系统配置,模块,组件间的通讯。这篇文章主要是聊一下Android property的应用和工作原理以及一些常用的系统属性。 属性配置文件在主板系统上,属性文件分别是: /default.prop -- 对应编译系统 out 目录下的 .../root/default.prop/system/build.prop -- 对应编译系统 out 目录下.../system/build.prop/data/property -- 这个目录下,是persist开头的可读写的属性。属性的规则以"ro."开头的属性, 一旦设置,就不能再被改变;非 "ro." 开头的属性值可以被修改。以"net."开头的属性,会被当作DNS属性,属于特殊属性,不要随便使用。以 "persist."开头的属性, 会保存到 /data/property/下面, 它是可以保存的;其它属性修改后,值不能保存,重启后无效。APIJava层:java API 主要是在系统预置apk和framework里面使用,它没有拉出来作为应用的API。 import android.os.SystemProperties;set(String key, String val)String get(String key, String def)int getInt(String key, int def)long getLong(String key, long def)boolean getBoolean(String key, boolean def)c 层: #include "cutils/properties.h"int property_get(const char *key, char *value, const char *default_value);int8_t property_get_bool(const char *key, int8_t default_value);int64_t property_get_int64(const char *key, int64_t default_value);int32_t property_get_int32(const char *key, int32_t default_value);int property_get(const char *key, char *value, const char *default_value)int property_set(const char *key, const char *value);bool 类型的有效值 ...

May 14, 2019 · 1 min · jiezi

Android-Low-Memory-Killer-机制

LowMemoryKiller是Android 系统在Linux kernel的OOMKiller基础上打的一个补丁。OOMKiller在kernel 没法再分配内存的时候,寻找一个得分最高的进程来杀掉。LowMemoryKiller则提前一步,通过把剩余内存划分成不同的级别,内存在消耗的过程中,触发不同的级别,杀死相应的app进程。在触发OOMKiller前,大量缓存的app进程已经被杀死掉了。 先简单说一下OOMKiller。 我们查看任一进程的proc信息(如:/proc/1), 都会看到以下三个参数: oom_score -- 是该进程的最终得分,分数越高,越容易被杀死;oom_score_adj -- 范围:[-1000, 1000],是kernel用来配置进程优先级的。值越低,最终的oom_score越低。oom_adj -- 范围:[-16, 15],是给用户来配置进程优先级的。为了方便用户配置,提供了范围更小的oom_adj参数,数字越小优先级越高,-17表示该进程被保护,不被OOMKiller杀死。因此,用户设置oom_adj后,kernel会转换并更新该进程实际的oom_score_adj值,它们的换算关系是: #define OOM_DISABLE (-17) #define OOM_SCORE_ADJ_MAX 1000 oom_score_adj = (oom_adj * OOM_SCORE_ADJ_MAX) / -OOM_DISABLE; oom_adj = (oom_score_adj * - OOM_DISABLE) / OOM_SCORE_ADJ_MAX;从上面可以看到,这个算法是有损的,所以,有时候会发现读出的oom_adj的值同设置得不一样了。如,设置oomajd=13, 那么 oom_score_adj=764,再次读oom_adj, 764 * 17 / 1000 == 12了。 当内存耗尽的时候,OOMKiller会调用 out_of_memory()来select_bad_process(), oom_score最大的值就是那个将要被杀死的bad process。 oom_badness()以oom_score_adj作为基础值,根据是否为管理员进程,占用的内存情况,来计算出最终的oom_score值,分值越高,越容易被杀死。 OOMKiller相应的源码文件: /fs/proc/base.c/mm/oom_kill.c在Android系统里面,当app的状态发生变化,如:创建,收到广播,唤醒,放入后台等, ActivityManagerService的updateOomAdjLocked() 会computeOomAdjLocked(),然后,通过applyOomAdjLocked()把app的oom_adj值写入到Linux Kernel。 那么AN是如何计算每个app最终的oom_adj值的呢? 我们知道oom_adj的范围是[-16, 15],AN根据app进程的特性进行了分类,不同的类别,对应不同的数值。 9 ~ 15: 是缓存到后台的app。8: service B 列表, 长时间未使用的service进程。7: 前一个app。6: Home app。5: 包含service的app 进程。4: 高权重的应用--隐藏的属性,AN P以上版本才能配置: android:cantSaveState="true"3: backup app--正在被备份的app。2: 用户可感知的后台进程,如:后台背景音乐播放器。1: 前台app启动的一些可见的组件,如: 弹出的Email activity。0: 前台app.-11: persistent service -- android:persistent:=true-12: 常驻内存的系统app--如:系统自带的拨号app。-16: 系统进程--如:system_server进程。-17: 不受oom_adj的管理,该进程不会被杀死,也native process的默认值。LowMemoryKiller注册了shrinker--Linux Kernel的一个内存管理工具,当kernel需要回收内存时,会回调LowMemoryKiller的lowmem_shrink(),它先检查kernel 剩下多少内存,根据剩下的内存数量来匹配数组 lowmem_minfree[], 找到数组索引值,然后,再使用该索引值,从 lowmem_adj[]这个数组里面就得到目标oom_adj值,最终,在大于等于该目标oom_adj的进程中,杀死拥有最大oom_adj值的进程--send_sig(SIGKILL, selected, 0) 。算法其实很简单,就是两个一维数组的映射。 ...

May 5, 2019 · 1 min · jiezi