Android Q以后,google推荐使用lmkd,lmkd其中一种工作模式是根据内存压力去kill进程.
https://source.android.google.cn/devices/tech/perf/lmkd文档中:
mem_pressure = 内存使用量/RAM_and_swap 使用量(以百分比的形式表示)
具体到代码中:
if ((mem_usage = get_memory_usage(&mem_usage_file_data)) < 0) { goto do_kill; } if ((memsw_usage = get_memory_usage(&memsw_usage_file_data)) < 0) { goto do_kill; } // Calculate percent for swappinness. mem_pressure = (mem_usage * 100) / memsw_usage; //添加log,能够查看内存压力等级 ALOGI("mem_usage = %lld KB memsw_usage = %lld KB mem_pressure = %lld " ,mem_usage/1024 , memsw_usage /1024,mem_pressure); if (enable_pressure_upgrade && level != VMPRESS_LEVEL_CRITICAL) { // We are swapping too much. if (mem_pressure < upgrade_pressure) { level = upgrade_level(level); if (debug_process_killing) { ALOGI("Event upgraded to %s", level_name[level]); } } }可以看到
mem_pressure = (mem_usage * 100) / memsw_usage; mem_usage = get_memory_usage(&mem_usage_file_data) memsw_usage = get_memory_usage(&memsw_usage_file_data)#define MEMCG_MEMORY_USAGE "/dev/memcg/memory.usage_in_bytes" #define MEMCG_MEMORYSW_USAGE "/dev/memcg/memory.memsw.usage_in_bytes"
从代码中看到查看到是去读取两个节点.这两个节点存储的数据的含义就是:
1.内存使用量
2.RAM_and_swap 使用量
我们具体去cat一下并且计算开机后的内存压力.
E:\02_Project>adb shell cat /dev/memcg/memory.usage_in_bytes 568688640
E:\02_Project>adb shell cat /dev/memcg/memory.memsw.usage_in_bytes 762757120
mem_pressure = 568688640*100/762757120 = 74.5
即现在样机的内存压力为74.5.
如果使用apk,那么zram会增加.mem_pressure的数值会变小.
mem_pressure的数值与以下系统属性有关.
ro.lmk.low=1001\ ro.lmk.medium=800\ ro.lmk.critical=0\ ro.lmk.upgrade_pressure=40\ ro.lmk.downgrade_pressure=60\从代码可以看到:
if (mem_pressure < upgrade_pressure) { level = upgrade_level(level); if (debug_process_killing) { ALOGI("Event upgraded to %s", level_name[level]); } }
和
if (mem_pressure > downgrade_pressure) { if (debug_process_killing) { ALOGI("Ignore %s memory pressure", level_name[level]); } return; } else if (level == VMPRESS_LEVEL_CRITICAL && mem_pressure > upgrade_pressure) { if (debug_process_killing) { ALOGI("Downgrade critical memory pressure"); } // Downgrade event, since enough memory available. level = downgrade_level(level); }
如果 mem_pressure<40 ,内存压力等级升级. 如果 mem_pressure > 60,内存压力等级降级
压力等级为:
enum vmpressure_level { VMPRESS_LEVEL_LOW = 0, VMPRESS_LEVEL_MEDIUM, VMPRESS_LEVEL_CRITICAL, VMPRESS_LEVEL_COUNT };
其中:
level与oomadj有对应关系.
/* By default disable low level vmpressure events */ level_oomadj[VMPRESS_LEVEL_LOW] = property_get_int32("ro.lmk.low", OOM_SCORE_ADJ_MAX + 1); level_oomadj[VMPRESS_LEVEL_MEDIUM] = property_get_int32("ro.lmk.medium", 900); level_oomadj[VMPRESS_LEVEL_CRITICAL] = property_get_int32("ro.lmk.critical", 0);
根据我们的配置:
ro.lmk.low = 1001
ro.lmk.medium = 800 ro.lmk.critical = 0
所以
level_oomadj[VMPRESS_LEVEL_LOW] =1001 level_oomadj[VMPRESS_LEVEL_MEDIUM] =800 level_oomadj[VMPRESS_LEVEL_CRITICAL] =0
下面是kill进程
if (low_ram_device) { /* For Go devices kill only one task */ if (find_and_kill_process(level_oomadj[level]) == 0) { if (debug_process_killing) { ALOGI("Nothing to kill"); } } else { meminfo_log(&mi); } }
level_oomadj[level]=1001/800/0
这里前面计算的level的等级会转换为oom_adj=1001/800/0
接下来会到:
retry: for (i = OOM_SCORE_ADJ_MAX; i >= min_score_adj; i--) { struct proc *procp; while (true) { procp = kill_heaviest_task ? proc_get_heaviest(i) : proc_adj_lru(i); if (!procp) break; killed_size = kill_one_process(procp, min_score_adj); if (killed_size >= 0) { #ifdef LMKD_LOG_STATS if (enable_stats_log && !lmk_state_change_start) { lmk_state_change_start = true; stats_write_lmk_state_changed(log_ctx, LMK_STATE_CHANGED, LMK_STATE_CHANGE_START); } #endif break; } } if (killed_size) { break; } }
killed_size = kill_one_process(procp, min_score_adj); kill_one_process中最终会调用:
r = kill(pid, SIGKILL);杀掉指定pid进程.
