• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.am;
18 
19 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
20 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
21 
22 import java.io.IOException;
23 import java.io.OutputStream;
24 import java.nio.ByteBuffer;
25 
26 import android.app.ActivityManager;
27 import android.os.Build;
28 import android.os.SystemClock;
29 import com.android.internal.util.MemInfoReader;
30 import com.android.server.wm.WindowManagerService;
31 
32 import android.content.res.Resources;
33 import android.graphics.Point;
34 import android.os.SystemProperties;
35 import android.net.LocalSocketAddress;
36 import android.net.LocalSocket;
37 import android.util.Slog;
38 import android.view.Display;
39 
40 /**
41  * Activity manager code dealing with processes.
42  */
43 final class ProcessList {
44     private static final String TAG = TAG_WITH_CLASS_NAME ? "ProcessList" : TAG_AM;
45 
46     // The minimum time we allow between crashes, for us to consider this
47     // application to be bad and stop and its services and reject broadcasts.
48     static final int MIN_CRASH_INTERVAL = 60*1000;
49 
50     // OOM adjustments for processes in various states:
51 
52     // Uninitialized value for any major or minor adj fields
53     static final int INVALID_ADJ = -10000;
54 
55     // Adjustment used in certain places where we don't know it yet.
56     // (Generally this is something that is going to be cached, but we
57     // don't know the exact value in the cached range to assign yet.)
58     static final int UNKNOWN_ADJ = 1001;
59 
60     // This is a process only hosting activities that are not visible,
61     // so it can be killed without any disruption.
62     static final int CACHED_APP_MAX_ADJ = 906;
63     static final int CACHED_APP_MIN_ADJ = 900;
64 
65     // The B list of SERVICE_ADJ -- these are the old and decrepit
66     // services that aren't as shiny and interesting as the ones in the A list.
67     static final int SERVICE_B_ADJ = 800;
68 
69     // This is the process of the previous application that the user was in.
70     // This process is kept above other things, because it is very common to
71     // switch back to the previous app.  This is important both for recent
72     // task switch (toggling between the two top recent apps) as well as normal
73     // UI flow such as clicking on a URI in the e-mail app to view in the browser,
74     // and then pressing back to return to e-mail.
75     static final int PREVIOUS_APP_ADJ = 700;
76 
77     // This is a process holding the home application -- we want to try
78     // avoiding killing it, even if it would normally be in the background,
79     // because the user interacts with it so much.
80     static final int HOME_APP_ADJ = 600;
81 
82     // This is a process holding an application service -- killing it will not
83     // have much of an impact as far as the user is concerned.
84     static final int SERVICE_ADJ = 500;
85 
86     // This is a process with a heavy-weight application.  It is in the
87     // background, but we want to try to avoid killing it.  Value set in
88     // system/rootdir/init.rc on startup.
89     static final int HEAVY_WEIGHT_APP_ADJ = 400;
90 
91     // This is a process currently hosting a backup operation.  Killing it
92     // is not entirely fatal but is generally a bad idea.
93     static final int BACKUP_APP_ADJ = 300;
94 
95     // This is a process only hosting components that are perceptible to the
96     // user, and we really want to avoid killing them, but they are not
97     // immediately visible. An example is background music playback.
98     static final int PERCEPTIBLE_APP_ADJ = 200;
99 
100     // This is a process only hosting activities that are visible to the
101     // user, so we'd prefer they don't disappear.
102     static final int VISIBLE_APP_ADJ = 100;
103     static final int VISIBLE_APP_LAYER_MAX = PERCEPTIBLE_APP_ADJ - VISIBLE_APP_ADJ - 1;
104 
105     // This is the process running the current foreground app.  We'd really
106     // rather not kill it!
107     static final int FOREGROUND_APP_ADJ = 0;
108 
109     // This is a process that the system or a persistent process has bound to,
110     // and indicated it is important.
111     static final int PERSISTENT_SERVICE_ADJ = -700;
112 
113     // This is a system persistent process, such as telephony.  Definitely
114     // don't want to kill it, but doing so is not completely fatal.
115     static final int PERSISTENT_PROC_ADJ = -800;
116 
117     // The system process runs at the default adjustment.
118     static final int SYSTEM_ADJ = -900;
119 
120     // Special code for native processes that are not being managed by the system (so
121     // don't have an oom adj assigned by the system).
122     static final int NATIVE_ADJ = -1000;
123 
124     // Memory pages are 4K.
125     static final int PAGE_SIZE = 4*1024;
126 
127     // Activity manager's version of Process.THREAD_GROUP_BG_NONINTERACTIVE
128     static final int SCHED_GROUP_BACKGROUND = 0;
129     // Activity manager's version of Process.THREAD_GROUP_DEFAULT
130     static final int SCHED_GROUP_DEFAULT = 1;
131     // Activity manager's version of Process.THREAD_GROUP_TOP_APP
132     static final int SCHED_GROUP_TOP_APP = 2;
133     // Activity manager's version of Process.THREAD_GROUP_TOP_APP
134     // Disambiguate between actual top app and processes bound to the top app
135     static final int SCHED_GROUP_TOP_APP_BOUND = 3;
136 
137     // The minimum number of cached apps we want to be able to keep around,
138     // without empty apps being able to push them out of memory.
139     static final int MIN_CACHED_APPS = 2;
140 
141     // The maximum number of cached processes we will keep around before killing them.
142     // NOTE: this constant is *only* a control to not let us go too crazy with
143     // keeping around processes on devices with large amounts of RAM.  For devices that
144     // are tighter on RAM, the out of memory killer is responsible for killing background
145     // processes as RAM is needed, and we should *never* be relying on this limit to
146     // kill them.  Also note that this limit only applies to cached background processes;
147     // we have no limit on the number of service, visible, foreground, or other such
148     // processes and the number of those processes does not count against the cached
149     // process limit.
150     static final int MAX_CACHED_APPS = 32;
151 
152     // We allow empty processes to stick around for at most 30 minutes.
153     static final long MAX_EMPTY_TIME = 30*60*1000;
154 
155     // The maximum number of empty app processes we will let sit around.
156     private static final int MAX_EMPTY_APPS = computeEmptyProcessLimit(MAX_CACHED_APPS);
157 
158     // The number of empty apps at which we don't consider it necessary to do
159     // memory trimming.
160     static final int TRIM_EMPTY_APPS = MAX_EMPTY_APPS/2;
161 
162     // The number of cached at which we don't consider it necessary to do
163     // memory trimming.
164     static final int TRIM_CACHED_APPS = (MAX_CACHED_APPS-MAX_EMPTY_APPS)/3;
165 
166     // Threshold of number of cached+empty where we consider memory critical.
167     static final int TRIM_CRITICAL_THRESHOLD = 3;
168 
169     // Threshold of number of cached+empty where we consider memory critical.
170     static final int TRIM_LOW_THRESHOLD = 5;
171 
172     // Low Memory Killer Daemon command codes.
173     // These must be kept in sync with the definitions in lmkd.c
174     //
175     // LMK_TARGET <minfree> <minkillprio> ... (up to 6 pairs)
176     // LMK_PROCPRIO <pid> <uid> <prio>
177     // LMK_PROCREMOVE <pid>
178     static final byte LMK_TARGET = 0;
179     static final byte LMK_PROCPRIO = 1;
180     static final byte LMK_PROCREMOVE = 2;
181 
182     // These are the various interesting memory levels that we will give to
183     // the OOM killer.  Note that the OOM killer only supports 6 slots, so we
184     // can't give it a different value for every possible kind of process.
185     private final int[] mOomAdj = new int[] {
186             FOREGROUND_APP_ADJ, VISIBLE_APP_ADJ, PERCEPTIBLE_APP_ADJ,
187             BACKUP_APP_ADJ, CACHED_APP_MIN_ADJ, CACHED_APP_MAX_ADJ
188     };
189     // These are the low-end OOM level limits.  This is appropriate for an
190     // HVGA or smaller phone with less than 512MB.  Values are in KB.
191     private final int[] mOomMinFreeLow = new int[] {
192             12288, 18432, 24576,
193             36864, 43008, 49152
194     };
195     // These are the high-end OOM level limits.  This is appropriate for a
196     // 1280x800 or larger screen with around 1GB RAM.  Values are in KB.
197     private final int[] mOomMinFreeHigh = new int[] {
198             73728, 92160, 110592,
199             129024, 147456, 184320
200     };
201     // The actual OOM killer memory levels we are using.
202     private final int[] mOomMinFree = new int[mOomAdj.length];
203 
204     private final long mTotalMemMb;
205 
206     private long mCachedRestoreLevel;
207 
208     private boolean mHaveDisplaySize;
209 
210     private static LocalSocket sLmkdSocket;
211     private static OutputStream sLmkdOutputStream;
212 
ProcessList()213     ProcessList() {
214         MemInfoReader minfo = new MemInfoReader();
215         minfo.readMemInfo();
216         mTotalMemMb = minfo.getTotalSize()/(1024*1024);
217         updateOomLevels(0, 0, false);
218     }
219 
applyDisplaySize(WindowManagerService wm)220     void applyDisplaySize(WindowManagerService wm) {
221         if (!mHaveDisplaySize) {
222             Point p = new Point();
223             wm.getBaseDisplaySize(Display.DEFAULT_DISPLAY, p);
224             if (p.x != 0 && p.y != 0) {
225                 updateOomLevels(p.x, p.y, true);
226                 mHaveDisplaySize = true;
227             }
228         }
229     }
230 
updateOomLevels(int displayWidth, int displayHeight, boolean write)231     private void updateOomLevels(int displayWidth, int displayHeight, boolean write) {
232         // Scale buckets from avail memory: at 300MB we use the lowest values to
233         // 700MB or more for the top values.
234         float scaleMem = ((float)(mTotalMemMb-350))/(700-350);
235 
236         // Scale buckets from screen size.
237         int minSize = 480*800;  //  384000
238         int maxSize = 1280*800; // 1024000  230400 870400  .264
239         float scaleDisp = ((float)(displayWidth*displayHeight)-minSize)/(maxSize-minSize);
240         if (false) {
241             Slog.i("XXXXXX", "scaleMem=" + scaleMem);
242             Slog.i("XXXXXX", "scaleDisp=" + scaleDisp + " dw=" + displayWidth
243                     + " dh=" + displayHeight);
244         }
245 
246         float scale = scaleMem > scaleDisp ? scaleMem : scaleDisp;
247         if (scale < 0) scale = 0;
248         else if (scale > 1) scale = 1;
249         int minfree_adj = Resources.getSystem().getInteger(
250                 com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAdjust);
251         int minfree_abs = Resources.getSystem().getInteger(
252                 com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAbsolute);
253         if (false) {
254             Slog.i("XXXXXX", "minfree_adj=" + minfree_adj + " minfree_abs=" + minfree_abs);
255         }
256 
257         final boolean is64bit = Build.SUPPORTED_64_BIT_ABIS.length > 0;
258 
259         for (int i=0; i<mOomAdj.length; i++) {
260             int low = mOomMinFreeLow[i];
261             int high = mOomMinFreeHigh[i];
262             if (is64bit) {
263                 // Increase the high min-free levels for cached processes for 64-bit
264                 if (i == 4) high = (high*3)/2;
265                 else if (i == 5) high = (high*7)/4;
266             }
267             mOomMinFree[i] = (int)(low + ((high-low)*scale));
268         }
269 
270         if (minfree_abs >= 0) {
271             for (int i=0; i<mOomAdj.length; i++) {
272                 mOomMinFree[i] = (int)((float)minfree_abs * mOomMinFree[i]
273                         / mOomMinFree[mOomAdj.length - 1]);
274             }
275         }
276 
277         if (minfree_adj != 0) {
278             for (int i=0; i<mOomAdj.length; i++) {
279                 mOomMinFree[i] += (int)((float)minfree_adj * mOomMinFree[i]
280                         / mOomMinFree[mOomAdj.length - 1]);
281                 if (mOomMinFree[i] < 0) {
282                     mOomMinFree[i] = 0;
283                 }
284             }
285         }
286 
287         // The maximum size we will restore a process from cached to background, when under
288         // memory duress, is 1/3 the size we have reserved for kernel caches and other overhead
289         // before killing background processes.
290         mCachedRestoreLevel = (getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024) / 3;
291 
292         // Ask the kernel to try to keep enough memory free to allocate 3 full
293         // screen 32bpp buffers without entering direct reclaim.
294         int reserve = displayWidth * displayHeight * 4 * 3 / 1024;
295         int reserve_adj = Resources.getSystem().getInteger(com.android.internal.R.integer.config_extraFreeKbytesAdjust);
296         int reserve_abs = Resources.getSystem().getInteger(com.android.internal.R.integer.config_extraFreeKbytesAbsolute);
297 
298         if (reserve_abs >= 0) {
299             reserve = reserve_abs;
300         }
301 
302         if (reserve_adj != 0) {
303             reserve += reserve_adj;
304             if (reserve < 0) {
305                 reserve = 0;
306             }
307         }
308 
309         if (write) {
310             ByteBuffer buf = ByteBuffer.allocate(4 * (2*mOomAdj.length + 1));
311             buf.putInt(LMK_TARGET);
312             for (int i=0; i<mOomAdj.length; i++) {
313                 buf.putInt((mOomMinFree[i]*1024)/PAGE_SIZE);
314                 buf.putInt(mOomAdj[i]);
315             }
316 
317             writeLmkd(buf);
318             SystemProperties.set("sys.sysctl.extra_free_kbytes", Integer.toString(reserve));
319         }
320         // GB: 2048,3072,4096,6144,7168,8192
321         // HC: 8192,10240,12288,14336,16384,20480
322     }
323 
computeEmptyProcessLimit(int totalProcessLimit)324     public static int computeEmptyProcessLimit(int totalProcessLimit) {
325         return totalProcessLimit/2;
326     }
327 
buildOomTag(String prefix, String space, int val, int base)328     private static String buildOomTag(String prefix, String space, int val, int base) {
329         if (val == base) {
330             if (space == null) return prefix;
331             return prefix + "  ";
332         }
333         return prefix + "+" + Integer.toString(val-base);
334     }
335 
makeOomAdjString(int setAdj)336     public static String makeOomAdjString(int setAdj) {
337         if (setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
338             return buildOomTag("cch", "  ", setAdj, ProcessList.CACHED_APP_MIN_ADJ);
339         } else if (setAdj >= ProcessList.SERVICE_B_ADJ) {
340             return buildOomTag("svcb ", null, setAdj, ProcessList.SERVICE_B_ADJ);
341         } else if (setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
342             return buildOomTag("prev ", null, setAdj, ProcessList.PREVIOUS_APP_ADJ);
343         } else if (setAdj >= ProcessList.HOME_APP_ADJ) {
344             return buildOomTag("home ", null, setAdj, ProcessList.HOME_APP_ADJ);
345         } else if (setAdj >= ProcessList.SERVICE_ADJ) {
346             return buildOomTag("svc  ", null, setAdj, ProcessList.SERVICE_ADJ);
347         } else if (setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
348             return buildOomTag("hvy  ", null, setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
349         } else if (setAdj >= ProcessList.BACKUP_APP_ADJ) {
350             return buildOomTag("bkup ", null, setAdj, ProcessList.BACKUP_APP_ADJ);
351         } else if (setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
352             return buildOomTag("prcp ", null, setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
353         } else if (setAdj >= ProcessList.VISIBLE_APP_ADJ) {
354             return buildOomTag("vis  ", null, setAdj, ProcessList.VISIBLE_APP_ADJ);
355         } else if (setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
356             return buildOomTag("fore ", null, setAdj, ProcessList.FOREGROUND_APP_ADJ);
357         } else if (setAdj >= ProcessList.PERSISTENT_SERVICE_ADJ) {
358             return buildOomTag("psvc ", null, setAdj, ProcessList.PERSISTENT_SERVICE_ADJ);
359         } else if (setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
360             return buildOomTag("pers ", null, setAdj, ProcessList.PERSISTENT_PROC_ADJ);
361         } else if (setAdj >= ProcessList.SYSTEM_ADJ) {
362             return buildOomTag("sys  ", null, setAdj, ProcessList.SYSTEM_ADJ);
363         } else if (setAdj >= ProcessList.NATIVE_ADJ) {
364             return buildOomTag("ntv  ", null, setAdj, ProcessList.NATIVE_ADJ);
365         } else {
366             return Integer.toString(setAdj);
367         }
368     }
369 
makeProcStateString(int curProcState)370     public static String makeProcStateString(int curProcState) {
371         String procState;
372         switch (curProcState) {
373             case -1:
374                 procState = "N ";
375                 break;
376             case ActivityManager.PROCESS_STATE_PERSISTENT:
377                 procState = "P ";
378                 break;
379             case ActivityManager.PROCESS_STATE_PERSISTENT_UI:
380                 procState = "PU";
381                 break;
382             case ActivityManager.PROCESS_STATE_TOP:
383                 procState = "T ";
384                 break;
385             case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
386                 procState = "SB";
387                 break;
388             case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
389                 procState = "SF";
390                 break;
391             case ActivityManager.PROCESS_STATE_TOP_SLEEPING:
392                 procState = "TS";
393                 break;
394             case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
395                 procState = "IF";
396                 break;
397             case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
398                 procState = "IB";
399                 break;
400             case ActivityManager.PROCESS_STATE_BACKUP:
401                 procState = "BU";
402                 break;
403             case ActivityManager.PROCESS_STATE_HEAVY_WEIGHT:
404                 procState = "HW";
405                 break;
406             case ActivityManager.PROCESS_STATE_SERVICE:
407                 procState = "S ";
408                 break;
409             case ActivityManager.PROCESS_STATE_RECEIVER:
410                 procState = "R ";
411                 break;
412             case ActivityManager.PROCESS_STATE_HOME:
413                 procState = "HO";
414                 break;
415             case ActivityManager.PROCESS_STATE_LAST_ACTIVITY:
416                 procState = "LA";
417                 break;
418             case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
419                 procState = "CA";
420                 break;
421             case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
422                 procState = "Ca";
423                 break;
424             case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
425                 procState = "CE";
426                 break;
427             default:
428                 procState = "??";
429                 break;
430         }
431         return procState;
432     }
433 
appendRamKb(StringBuilder sb, long ramKb)434     public static void appendRamKb(StringBuilder sb, long ramKb) {
435         for (int j=0, fact=10; j<6; j++, fact*=10) {
436             if (ramKb < fact) {
437                 sb.append(' ');
438             }
439         }
440         sb.append(ramKb);
441     }
442 
443     // How long after a state change that it is safe to collect PSS without it being dirty.
444     public static final int PSS_SAFE_TIME_FROM_STATE_CHANGE = 1000;
445 
446     // The minimum time interval after a state change it is safe to collect PSS.
447     public static final int PSS_MIN_TIME_FROM_STATE_CHANGE = 15*1000;
448 
449     // The maximum amount of time we want to go between PSS collections.
450     public static final int PSS_MAX_INTERVAL = 30*60*1000;
451 
452     // The minimum amount of time between successive PSS requests for *all* processes.
453     public static final int PSS_ALL_INTERVAL = 10*60*1000;
454 
455     // The minimum amount of time between successive PSS requests for a process.
456     private static final int PSS_SHORT_INTERVAL = 2*60*1000;
457 
458     // The amount of time until PSS when a process first becomes top.
459     private static final int PSS_FIRST_TOP_INTERVAL = 10*1000;
460 
461     // The amount of time until PSS when a process first goes into the background.
462     private static final int PSS_FIRST_BACKGROUND_INTERVAL = 20*1000;
463 
464     // The amount of time until PSS when a process first becomes cached.
465     private static final int PSS_FIRST_CACHED_INTERVAL = 30*1000;
466 
467     // The amount of time until PSS when an important process stays in the same state.
468     private static final int PSS_SAME_IMPORTANT_INTERVAL = 15*60*1000;
469 
470     // The amount of time until PSS when a service process stays in the same state.
471     private static final int PSS_SAME_SERVICE_INTERVAL = 20*60*1000;
472 
473     // The amount of time until PSS when a cached process stays in the same state.
474     private static final int PSS_SAME_CACHED_INTERVAL = 30*60*1000;
475 
476     // The minimum time interval after a state change it is safe to collect PSS.
477     public static final int PSS_TEST_MIN_TIME_FROM_STATE_CHANGE = 10*1000;
478 
479     // The amount of time during testing until PSS when a process first becomes top.
480     private static final int PSS_TEST_FIRST_TOP_INTERVAL = 3*1000;
481 
482     // The amount of time during testing until PSS when a process first goes into the background.
483     private static final int PSS_TEST_FIRST_BACKGROUND_INTERVAL = 5*1000;
484 
485     // The amount of time during testing until PSS when an important process stays in same state.
486     private static final int PSS_TEST_SAME_IMPORTANT_INTERVAL = 10*1000;
487 
488     // The amount of time during testing until PSS when a background process stays in same state.
489     private static final int PSS_TEST_SAME_BACKGROUND_INTERVAL = 15*1000;
490 
491     public static final int PROC_MEM_PERSISTENT = 0;
492     public static final int PROC_MEM_TOP = 1;
493     public static final int PROC_MEM_IMPORTANT = 2;
494     public static final int PROC_MEM_SERVICE = 3;
495     public static final int PROC_MEM_CACHED = 4;
496 
497     private static final int[] sProcStateToProcMem = new int[] {
498         PROC_MEM_PERSISTENT,            // ActivityManager.PROCESS_STATE_PERSISTENT
499         PROC_MEM_PERSISTENT,            // ActivityManager.PROCESS_STATE_PERSISTENT_UI
500         PROC_MEM_TOP,                   // ActivityManager.PROCESS_STATE_TOP
501         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
502         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
503         PROC_MEM_TOP,                   // ActivityManager.PROCESS_STATE_TOP_SLEEPING
504         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
505         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
506         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_BACKUP
507         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
508         PROC_MEM_SERVICE,               // ActivityManager.PROCESS_STATE_SERVICE
509         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_RECEIVER
510         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_HOME
511         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
512         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
513         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
514         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_CACHED_EMPTY
515     };
516 
517     private static final long[] sFirstAwakePssTimes = new long[] {
518         PSS_SHORT_INTERVAL,             // ActivityManager.PROCESS_STATE_PERSISTENT
519         PSS_SHORT_INTERVAL,             // ActivityManager.PROCESS_STATE_PERSISTENT_UI
520         PSS_FIRST_TOP_INTERVAL,         // ActivityManager.PROCESS_STATE_TOP
521         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
522         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
523         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_TOP_SLEEPING
524         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
525         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
526         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_BACKUP
527         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
528         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_SERVICE
529         PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_RECEIVER
530         PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_HOME
531         PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
532         PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
533         PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
534         PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_CACHED_EMPTY
535     };
536 
537     private static final long[] sSameAwakePssTimes = new long[] {
538         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_PERSISTENT
539         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_PERSISTENT_UI
540         PSS_SHORT_INTERVAL,             // ActivityManager.PROCESS_STATE_TOP
541         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
542         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
543         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_TOP_SLEEPING
544         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
545         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
546         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_BACKUP
547         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
548         PSS_SAME_SERVICE_INTERVAL,      // ActivityManager.PROCESS_STATE_SERVICE
549         PSS_SAME_SERVICE_INTERVAL,      // ActivityManager.PROCESS_STATE_RECEIVER
550         PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_HOME
551         PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
552         PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
553         PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
554         PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_EMPTY
555     };
556 
557     private static final long[] sTestFirstAwakePssTimes = new long[] {
558         PSS_TEST_FIRST_TOP_INTERVAL,        // ActivityManager.PROCESS_STATE_PERSISTENT
559         PSS_TEST_FIRST_TOP_INTERVAL,        // ActivityManager.PROCESS_STATE_PERSISTENT_UI
560         PSS_TEST_FIRST_TOP_INTERVAL,        // ActivityManager.PROCESS_STATE_TOP
561         PSS_FIRST_BACKGROUND_INTERVAL,      // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
562         PSS_FIRST_BACKGROUND_INTERVAL,      // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
563         PSS_FIRST_BACKGROUND_INTERVAL,      // ActivityManager.PROCESS_STATE_TOP_SLEEPING
564         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
565         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
566         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_BACKUP
567         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
568         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_SERVICE
569         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_RECEIVER
570         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_HOME
571         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
572         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
573         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
574         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_EMPTY
575     };
576 
577     private static final long[] sTestSameAwakePssTimes = new long[] {
578         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_PERSISTENT
579         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_PERSISTENT_UI
580         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_TOP
581         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
582         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
583         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_TOP_SLEEPING
584         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
585         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
586         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_BACKUP
587         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
588         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_SERVICE
589         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_RECEIVER
590         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_HOME
591         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
592         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
593         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
594         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_CACHED_EMPTY
595     };
596 
procStatesDifferForMem(int procState1, int procState2)597     public static boolean procStatesDifferForMem(int procState1, int procState2) {
598         return sProcStateToProcMem[procState1] != sProcStateToProcMem[procState2];
599     }
600 
minTimeFromStateChange(boolean test)601     public static long minTimeFromStateChange(boolean test) {
602         return test ? PSS_TEST_MIN_TIME_FROM_STATE_CHANGE : PSS_MIN_TIME_FROM_STATE_CHANGE;
603     }
604 
computeNextPssTime(int procState, boolean first, boolean test, boolean sleeping, long now)605     public static long computeNextPssTime(int procState, boolean first, boolean test,
606             boolean sleeping, long now) {
607         final long[] table = test
608                 ? (first
609                         ? sTestFirstAwakePssTimes
610                         : sTestSameAwakePssTimes)
611                 : (first
612                         ? sFirstAwakePssTimes
613                         : sSameAwakePssTimes);
614         return now + table[procState];
615     }
616 
getMemLevel(int adjustment)617     long getMemLevel(int adjustment) {
618         for (int i=0; i<mOomAdj.length; i++) {
619             if (adjustment <= mOomAdj[i]) {
620                 return mOomMinFree[i] * 1024;
621             }
622         }
623         return mOomMinFree[mOomAdj.length-1] * 1024;
624     }
625 
626     /**
627      * Return the maximum pss size in kb that we consider a process acceptable to
628      * restore from its cached state for running in the background when RAM is low.
629      */
getCachedRestoreThresholdKb()630     long getCachedRestoreThresholdKb() {
631         return mCachedRestoreLevel;
632     }
633 
634     /**
635      * Set the out-of-memory badness adjustment for a process.
636      *
637      * @param pid The process identifier to set.
638      * @param uid The uid of the app
639      * @param amt Adjustment value -- lmkd allows -16 to +15.
640      *
641      * {@hide}
642      */
setOomAdj(int pid, int uid, int amt)643     public static final void setOomAdj(int pid, int uid, int amt) {
644         if (amt == UNKNOWN_ADJ)
645             return;
646 
647         long start = SystemClock.elapsedRealtime();
648         ByteBuffer buf = ByteBuffer.allocate(4 * 4);
649         buf.putInt(LMK_PROCPRIO);
650         buf.putInt(pid);
651         buf.putInt(uid);
652         buf.putInt(amt);
653         writeLmkd(buf);
654         long now = SystemClock.elapsedRealtime();
655         if ((now-start) > 250) {
656             Slog.w("ActivityManager", "SLOW OOM ADJ: " + (now-start) + "ms for pid " + pid
657                     + " = " + amt);
658         }
659     }
660 
661     /*
662      * {@hide}
663      */
remove(int pid)664     public static final void remove(int pid) {
665         ByteBuffer buf = ByteBuffer.allocate(4 * 2);
666         buf.putInt(LMK_PROCREMOVE);
667         buf.putInt(pid);
668         writeLmkd(buf);
669     }
670 
openLmkdSocket()671     private static boolean openLmkdSocket() {
672         try {
673             sLmkdSocket = new LocalSocket(LocalSocket.SOCKET_SEQPACKET);
674             sLmkdSocket.connect(
675                 new LocalSocketAddress("lmkd",
676                         LocalSocketAddress.Namespace.RESERVED));
677             sLmkdOutputStream = sLmkdSocket.getOutputStream();
678         } catch (IOException ex) {
679             Slog.w(TAG, "lowmemorykiller daemon socket open failed");
680             sLmkdSocket = null;
681             return false;
682         }
683 
684         return true;
685     }
686 
writeLmkd(ByteBuffer buf)687     private static void writeLmkd(ByteBuffer buf) {
688 
689         for (int i = 0; i < 3; i++) {
690             if (sLmkdSocket == null) {
691                     if (openLmkdSocket() == false) {
692                         try {
693                             Thread.sleep(1000);
694                         } catch (InterruptedException ie) {
695                         }
696                         continue;
697                     }
698             }
699 
700             try {
701                 sLmkdOutputStream.write(buf.array(), 0, buf.position());
702                 return;
703             } catch (IOException ex) {
704                 Slog.w(TAG, "Error writing to lowmemorykiller socket");
705 
706                 try {
707                     sLmkdSocket.close();
708                 } catch (IOException ex2) {
709                 }
710 
711                 sLmkdSocket = null;
712             }
713         }
714     }
715 }
716