一个好的性能测试指标应该满足 2 个条件:
对过去发生的事情做总结.
对未来做预期.
Settings->Memory就很好地实现了这 2 个条件:
[3 hours]: 表示统计过去 3 小时 RAM 的使用情况. 使用者还可以选择 6 小时, 12 小时, 1 天.
[Performance]: 表示手机当前的性能情况. 这里有一套 Google 的性能评价标准.
[Total memory]/[Average used]/[Free]: 统计时间内 RAM 的平均使用情况. 特别是 Free, 这里也有一套 Google 的性能评价标准.
—— 这 2 个评价标准是本次的重点.
[Performance] —— 该指标的评价标准.
这是 Google 的即时指标. 仅表示打开 memory 这个页面时, 手机的 RAM 情况.
Google 的理念仍然是: RAM 不使用就是浪费, 与其浪费, 不如用来做 Cached. 所以, 当 Cached 数量少于一定数值的时候, 就表示内存不足了. 在 Kernel Space, 使用 minfree 来做衡量 Cached 是否充足的指标; 在 User Space, 使用 memFactor 来做衡量 Cached 是否充足的指标.
memFactor是这样定义的:
android/platform/frameworks/base/nougat-release/./services/core/java/com/android/server/am/ActivityManagerService.java |
// Now determine the memory trimming level of background processes. // Unfortunately we need to start at the back of the list to do this // properly. We only do this if the number of background apps we // are managing to keep around is less than half the maximum we desire; // if we are keeping a good number around, we'll let them use whatever // memory they want. final int numCachedAndEmpty = numCached + numEmpty; int memFactor; if (numCached <= ProcessList.TRIM_CACHED_APPS && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; } else { memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; } } else { memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; } |
也就是:
Cached Process + Empty Process <= 3 个, 则认为 Critical Memory
Cached Process + Empty Process <= 5 个, 则认为 Low Memory
Cached Process <= 5 个, 而且 Empty Process <= 8 个, 则认为 Moderate Memory
其他情况则认为 Normal Memory
如果修改了 MAX_CACHED_APPS, 如上的 Threshold 也会被重新计算.
// The maximum number of cached processes we will keep around before killing them. // NOTE: this constant is *only* a control to not let us go too crazy with // keeping around processes on devices with large amounts of RAM. For devices that // are tighter on RAM, the out of memory killer is responsible for killing background // processes as RAM is needed, and we should *never* be relying on this limit to // kill them. Also note that this limit only applies to cached background processes; // we have no limit on the number of service, visible, foreground, or other such // processes and the number of those processes does not count against the cached // process limit. static final int MAX_CACHED_APPS = 32; |
[Free] —— 该指标的评价标准.
这是 Google 在 M 上加入的历史指标. 该指标不仅仅计算了过去一段时间的 Free RAM 情况, 而且特别在算法上加入了 Safe RAM 对未来的手机性能做预测.
android/platform/packages/apps/Settings/nougat-release/./src/com/android/settings/applications/ProcStatsData.java |
if (memInfo.hiddenAppThreshold >= realFreeRam) { realUsedRam = freeRam; realFreeRam = 0; baseCacheRam = (long) realFreeRam; } else { realUsedRam += memInfo.hiddenAppThreshold; realFreeRam -= memInfo.hiddenAppThreshold; baseCacheRam = memInfo.hiddenAppThreshold; } |
在这里有 2 个点需要注意:
memInfo.hiddenAppThreshold. 这是 ADJ=9 对应的水位. 也就是如下的 55296 x 4K = 216M
>adb shell cat /sys/module/lowmemorykiller/parameters/minfree 18432,23040,27648,32256,55296,80640 |
realFreeRam. 它包括 4 个部分, 分别是 Free + Cached + Buffer – Mapped.
如果统计得到的 realFreeRam 多于216M, 就在 realFreeRam 中扣除 216M, 获得的就是 App 可以使用的 Free RAM.
如果统计得到的 realFreeRam 少于216M, 那么表示 safe 空间已经被用完, App 可以使用的 Free RAM 就是 0.
会有这样的声音: 当 Free 为 0 时, 手机还是可以正常运行啊? 这个数据是不是错误的?
Google 之所以设计这个算法, 是因为有这样一个事实: 当 LMK 杀到 ADJ<9 的进程后, 手机性能会开始下降. 一开始并不明显, 但随着使用时间的增加, 下降会越来越明显, 越来越快.
所以 Google 使用 ADJ=9 的 minfree 做 Safe RAM, 是有价值并且很明智的.
对于使用者, 通过这个指标, 可以很简单知道自己的操作习惯对手机性能的影响.
因为这套指标会让数据变得很不漂亮, 很多产品会排斥. 但是作为 PM, 这套指标会让你的产品变得更 safe.
为了数据漂亮, 减少 minfree 会是一个做法. 但是另一个事实是, 调低水位, 会让 RAM 变得紧张, 增加 swap, 从而使得手机变慢. 如果使用的 eMMC 性能并不好, 请不要这样做. 增加 RAM, 减少预置功能, 积极做进程清理才是王道.
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。