Android P lmkd新增了许多机制和属性,包括引入原来内核的minfree算法等,看样子是越来越复杂了,下面来看看,内核版本4.9,高通平台。
how to kill
先看下应该杀掉哪个process or 哪些processes(yes, 已经支持)?
主要改动是:
support kill heaviest process
support kill multiple processes
/* * Find processes to kill to free required number of pages. * If pages_to_free is set to 0 only one process will be killed. * Returns the size of the killed processes. */ staticintfind_and_kill_processes(enum vmpressure_level level, int min_score_adj, int pages_to_free) { int i; int killed_size; int pages_freed = 0;
if (enhance_batch_kill) { // Kill one process at a time. pages_to_free = 0; } else { /* Original minfree logic */ /* Free up enough pages to push over the highest minfree level */ pages_to_free = lowmem_minfree[lowmem_targets_size - 1] - ((other_free < other_file) ? other_free : other_file); }
如果要杀多个进程,就是把那个距离minfree的差值要释放出来。
另外,高通加的这段:
// Adaptive LMK if (enable_adaptive_lmk && level == VMPRESS_LEVEL_CRITICAL && i > lowmem_targets_size-4) { min_score_adj = lowmem_adj[i-1]; }
就是在critical内存特紧张时,可以杀更低一级的adj的task。
ok,下来看下计算swapping是否频繁:
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; }
下来根据swapping情况判断是否要upgrade or downgrade level,默认关闭了, go上使能。
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]); } } }
// If the pressure is larger than downgrade_pressure lmk will not // kill any process, since enough memory is available. if (mem_pressure > downgrade_pressure) { if (debug_process_killing) { ALOGI("Ignore %s memory pressure", level_name[level]); } return; } elseif (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); }
以前的文章已经分析过。
下来看do_kill:
do_kill: if (low_ram_device) { /* For Go devices kill only one task */ if (find_and_kill_processes(level, level_oomadj[level], 0) == 0) { if (debug_process_killing) { ALOGI("Nothing to kill"); } } } else {
if (!use_minfree_levels) { /* If pressure level is less than critical and enough free swap then ignore */ if (level < VMPRESS_LEVEL_CRITICAL && mi.field.free_swap > low_pressure_mem.max_nr_free_pages) { if (debug_process_killing) { ALOGI("Ignoring pressure since %" PRId64 " swap pages are available ", mi.field.free_swap); } return; } /* Free up enough memory to downgrate the memory pressure to low level */ if (mi.field.nr_free_pages < low_pressure_mem.max_nr_free_pages) { pages_to_free = low_pressure_mem.max_nr_free_pages - mi.field.nr_free_pages; } else { if (debug_process_killing) { ALOGI("Ignoring pressure since more memory is " "available (%" PRId64 ") than watermark (%" PRId64 ")", mi.field.nr_free_pages, low_pressure_mem.max_nr_free_pages); } return; } min_score_adj = level_oomadj[level]; }
if event level is low or medium, 那么看下如果有足够的free swap,就不杀了,如果没有就要释放enough memory到low pressure memory的free水平。rt?