Clever women can cook for less rice (2) -- ghost Picker (lmk)

Source: Internet
Author: User

A friend of Android may have encountered this problem: an application is in use, and suddenly it is disabled, or an application is opened, and then it exits, in fact, lmk (low memory killer) is working, and all images are called Ghost executors.


1. Version Platform

2. Concepts

3. Core Structure and call

4. Summary


Version Platform
Platform: Qualcomm msm8974 Android: 4.4linux kernel: 3.4.4 file path: Android \ kernel \ drivers \ staging \ Android \ lowmemorykiller. c
Concept:

As mentioned above, lmk periodically scans the memory in the system. When the system memory is less than a certain valve value, it will selectively release some memory (killing processes ), this is why you can see that the current program suddenly exits. Someone may ask, why is the system not user-friendly? The system detects that I am using it and does not kill the program I am using, kill other things. Here we will come later ~~


Core Structure and call
The valve value lmk to kill memory is to choose which processes to kill Based on the valve value. Let's first look at the two data structures related to the valve value:
static int lowmem_adj[6] = {0,1,6,12,};static int lowmem_adj_size = 4;
static int lowmem_minfree[6] = {3 * 512,/* 6MB */2 * 1024,/* 8MB */4 * 1024,/* 16MB */16 * 1024,/* 64MB */};static int lowmem_minfree_size = 4;
These two data structures are only interrelated. How do they work together? For example, when the system's idle memory is 6 MB, it is smaller than lowmem_minfree [3] and greater than lowmem_minfree [2]. the standard value of the process to be killed (each process has an adj value) is lowmem_adj [3]. That is to say, find the process whose adj value is greater than lowmem_adj [3, then, find out the maximum value of the adj to kill from them. If there are two processes with the same value of the adj, the maximum memory usage will be selected to kill! Other parts of the array. Similarly, Android divides the process into six levels: foreground (foreground process), visible process (visible process), secondary server (secondary service), and hidden (background process) content Provider (content supply node), empty (empty process), the priority is reduced in turn, so we can see that the most vulnerable to death is the empty process, the most difficult thing to be killed is the front-end process. When the application you are using is killed, it indicates that the system's valve value has reached the bottom, have you enabled many applications?
Lowmem_shrink (): lmk indicates that the kernel module is registered to the kernel. during initialization, a shrink () is initialized and registered. (The shrink knowledge about Linux is not described here ), when the idle memory hits the valve value, it calls the lowmem_shrink () function, which is the place where the process's core operations are selected and killed, let's take a closer look at its process and code:
P = find_lock_task_mm (TSK);/* The thread with mm can be operated */If (! P) continue;/* obtain the oom_score_adj */oom_score_adj = p-> signal-> oom_score_adj corresponding to the task;/* is ignored if it is less than the current basic standard. */If (oom_score_adj <min_score_adj) {task_unlock (p); continue ;}
First, the system scans the process list to check whether the current process has mm. Only processes with MM can perform the following operations, if it is found, the value of oom_score_adj of the current process is obtained (that is, the value of adj of the process ), then, judge whether the current process's adj value is smaller than the benchmark value (find the process that is larger than the benchmark value and the biggest one to kill. Do not forget the one we just mentioned ~)
/* Obtain the RSS memory usage of this process */tasksize = get_mm_rss (p-> mm); task_unlock (p); If (tasksize <= 0) continue;
If you find a process that is larger than the reference value, record the memory size of the Process, in case two processes with the same value as the reference value will be killed if they occupy more memory.
If (selected) {/* If the OOM score of the current task is smaller than the previous one, no processing will be performed */If (oom_score_adj <selected_oom_score_adj) continue;
/* If the OOM score of the first and second tasks is the same, and the memory occupied by the task is <span style = "white-space: pre"> </span> compared to the last task hour, do not process. */If (oom_score_adj = selected_oom_score_adj & tasksize <= selected_tasksize) continue ;}
The following problem is the simplest problem: Find the maximum value of adj in a linked list by comparing the two. If the value is the same, find the value that occupies the maximum tasksize of the memory, in this way, we will select who the process to be killed is, and then let's look at it:
selected = p;selected_tasksize = tasksize;selected_oom_score_adj = oom_score_adj;lowmem_print(2, "select %d (%s), adj %d, size %d, to kill\n",     p->pid, p->comm, oom_score_adj, tasksize);}
This code updates the value of selected so that the next comparison can always ensure that the value of adj in selected is the largest and it occupies the largest memory, of course, I want to kill it and release the memory ~~ Kill:
If (selected) {lowmem_print (1, "Send sigkill to % d (% s), adj % d, size % d \ n", selected-> PID, selected-> comm, selected_oom_score_adj, selected_tasksize); bytes = jiffies + Hz; send_sig (sigkill, selected, 0);/* Send sigkill signal to kill process */set_tsk_thread_flag, tif_memdie); REM-= selected_tasksize;} lowmem_print (4, "lowmem_shrink % lu, % x, return % d \ n", SC-> nr_to_scan, SC-> gfp_mask, REM); rcu_read_unlock (); Return REM ;}
If I see it, I finally called the sigkill signal to let the Linux kernel kill the process, and I used a knife to kill it. This method is excellent. After the lowmem_adj and lowmem_minfree values are modified for Android 4.0, the operations on the two arrays before Android 4.0 are changed and the file paths of the two data sizes are operated: android \ frameworks \ base \ Services \ Java \ com \ Android \ Server \ am \ processlist. java
private final int[] mOomAdj = new int[] {    FOREGROUND_APP_ADJ, VISIBLE_APP_ADJ, PERCEPTIBLE_APP_ADJ,    BACKUP_APP_ADJ, HIDDEN_APP_MIN_ADJ, HIDDEN_APP_MAX_ADJ};
   // These are the low-end OOM level limits.  This is appropriate for an    // HVGA or smaller phone with less than 512MB.  Values are in KB.    private final long[] mOomMinFreeLow = new long[] {            8192, 12288, 16384,            24576, 28672, 32768    };    // These are the high-end OOM level limits.  This is appropriate for a    // 1280x800 or larger screen with around 1GB RAM.  Values are in KB.    private final long[] mOomMinFreeHigh = new long[] {            49152, 61440, 73728,            86016, 98304, 122880    };    // The actual OOM killer memory levels we are using.    private final long[] mOomMinFree = new long[mOomAdj.length];
Finally, oomminfreelow and moomminfreehigh are computed, and the final value is stored in moomminfree. How to calculate this value is based on the resolution and memory size of the current screen, it can be seen from the English comments. The last value is updated in the updateoomlevels function, which is also in processlist. java.
        for (int i=0; i<mOomAdj.length; i++) {            long low = mOomMinFreeLow[i];            long high = mOomMinFreeHigh[i];            mOomMinFree[i] = (long)(low + ((high-low)*scale));        }
The scale value is determined based on the memory and resolution. It has only two values, if not 0 or 1, there are some fault tolerance operations later, and finally determine the value of moomminfree, is it complicated? Yes, I am also very complicated!
       for (int i=0; i<mOomAdj.length; i++) {            if (i > 0) {                adjString.append(',');                memString.append(',');            }            adjString.append(mOomAdj[i]);            memString.append((mOomMinFree[i]*1024)/PAGE_SIZE);        }
..... // Some code is omitted here
//Slog.i("XXXXXXX", "******************************* MINFREE: " + memString);        if (write) {            writeFile("/sys/module/lowmemorykiller/parameters/adj", adjString.toString());            writeFile("/sys/module/lowmemorykiller/parameters/minfree", memString.toString());            SystemProperties.set("sys.sysctl.extra_free_kbytes", Integer.toString(reserve));        }        // GB: 2048,3072,4096,6144,7168,8192        // HC: 8192,10240,12288,14336,16384,20480
Finally, when the update is over, it writes the value to the system, therefore, you can query the current valve value in node/sys/module/lowmemorykiller/parameters/adj and minfree.
Summary
After talking about so much code, you may be reading a little boring. Here we will talk about the actual situation, which is also a summary of my feelings.
1. system processes will not be killed by lowmemorykiller, because the value of the adj of important system applications is set to-16 and-12. There are so many processes on the upper layer that are greater than 0, they are safe.
2. during use, I found several points. If the memory is too small, such as 1 GB memory, the process will often be killed. This is why a text message suddenly came during QQ chat, you can view and play the text message back to QQ. Sometimes you need to load it again. Sometimes you can directly return to the interface before exiting, depending on whether QQ has been killed.
3. small memory machine sub-Power Consumption: this is true, some mobile phone optimization is not good, this will happen, some processes are constantly killed, and then up again (this process is a lot, some of them are registered with the service. If they detect that their subject has been killed, they will start another one at an appropriate time.) They will then be killed and then restarted, in this way, the power consumption of the mobile phone comes up. You may not have encountered it, that is, your desktop will be normal for a while, and it will be displayed as loading again. This means that the desktop Restart service is working with lowmemorykiller.
4. Why does Android consume so much memory? Android uses a Java virtual machine. A bad habit of Java programmers is to open up the memory and release it manually, waiting for the garbage collection of the system to be released. The Linux kernel for Android is different from that for Windows. The idea is that the more physical memory is used, the better. The higher the utilization rate, the idea is different from that for Windows, it is confident that it can provide a better user experience. Android enables some programs to start when they are started, in order to make the user pre-loaded before opening, loading faster when clicking, the idea is good, but for those built-in junk applications of the manufacturer, I don't need it anymore, so what's the situation that it occupies my memory all year round? Who will explain it?
5. An article about how to set the valve value is recommended: How to reasonably set the valve value
6. buy a mobile phone with a large memory, at least 2 GB, It is not expensive now, about 2000 yuan, it is not expensive, buy a better mobile phone, it is more comfortable to use, the mood is good, the work is also comfortable, don't worry too much about 1 GB of mobile phones. It's better to be alive.
7. Google said that the M memory runs smoothly. I am so happy to wait for the performance of Android one.

Clever women can cook for less rice (2) -- ghost Picker (lmk)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.