• 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     // We allow empty processes to stick around for at most 30 minutes.
142     static final long MAX_EMPTY_TIME = 30*60*1000;
143 
144     // Threshold of number of cached+empty where we consider memory critical.
145     static final int TRIM_CRITICAL_THRESHOLD = 3;
146 
147     // Threshold of number of cached+empty where we consider memory critical.
148     static final int TRIM_LOW_THRESHOLD = 5;
149 
150     // Low Memory Killer Daemon command codes.
151     // These must be kept in sync with the definitions in lmkd.c
152     //
153     // LMK_TARGET <minfree> <minkillprio> ... (up to 6 pairs)
154     // LMK_PROCPRIO <pid> <uid> <prio>
155     // LMK_PROCREMOVE <pid>
156     static final byte LMK_TARGET = 0;
157     static final byte LMK_PROCPRIO = 1;
158     static final byte LMK_PROCREMOVE = 2;
159 
160     // These are the various interesting memory levels that we will give to
161     // the OOM killer.  Note that the OOM killer only supports 6 slots, so we
162     // can't give it a different value for every possible kind of process.
163     private final int[] mOomAdj = new int[] {
164             FOREGROUND_APP_ADJ, VISIBLE_APP_ADJ, PERCEPTIBLE_APP_ADJ,
165             BACKUP_APP_ADJ, CACHED_APP_MIN_ADJ, CACHED_APP_MAX_ADJ
166     };
167     // These are the low-end OOM level limits.  This is appropriate for an
168     // HVGA or smaller phone with less than 512MB.  Values are in KB.
169     private final int[] mOomMinFreeLow = new int[] {
170             12288, 18432, 24576,
171             36864, 43008, 49152
172     };
173     // These are the high-end OOM level limits.  This is appropriate for a
174     // 1280x800 or larger screen with around 1GB RAM.  Values are in KB.
175     private final int[] mOomMinFreeHigh = new int[] {
176             73728, 92160, 110592,
177             129024, 147456, 184320
178     };
179     // The actual OOM killer memory levels we are using.
180     private final int[] mOomMinFree = new int[mOomAdj.length];
181 
182     private final long mTotalMemMb;
183 
184     private long mCachedRestoreLevel;
185 
186     private boolean mHaveDisplaySize;
187 
188     private static LocalSocket sLmkdSocket;
189     private static OutputStream sLmkdOutputStream;
190 
ProcessList()191     ProcessList() {
192         MemInfoReader minfo = new MemInfoReader();
193         minfo.readMemInfo();
194         mTotalMemMb = minfo.getTotalSize()/(1024*1024);
195         updateOomLevels(0, 0, false);
196     }
197 
applyDisplaySize(WindowManagerService wm)198     void applyDisplaySize(WindowManagerService wm) {
199         if (!mHaveDisplaySize) {
200             Point p = new Point();
201             // TODO(multi-display): Compute based on sum of all connected displays' resolutions.
202             wm.getBaseDisplaySize(Display.DEFAULT_DISPLAY, p);
203             if (p.x != 0 && p.y != 0) {
204                 updateOomLevels(p.x, p.y, true);
205                 mHaveDisplaySize = true;
206             }
207         }
208     }
209 
updateOomLevels(int displayWidth, int displayHeight, boolean write)210     private void updateOomLevels(int displayWidth, int displayHeight, boolean write) {
211         // Scale buckets from avail memory: at 300MB we use the lowest values to
212         // 700MB or more for the top values.
213         float scaleMem = ((float)(mTotalMemMb-350))/(700-350);
214 
215         // Scale buckets from screen size.
216         int minSize = 480*800;  //  384000
217         int maxSize = 1280*800; // 1024000  230400 870400  .264
218         float scaleDisp = ((float)(displayWidth*displayHeight)-minSize)/(maxSize-minSize);
219         if (false) {
220             Slog.i("XXXXXX", "scaleMem=" + scaleMem);
221             Slog.i("XXXXXX", "scaleDisp=" + scaleDisp + " dw=" + displayWidth
222                     + " dh=" + displayHeight);
223         }
224 
225         float scale = scaleMem > scaleDisp ? scaleMem : scaleDisp;
226         if (scale < 0) scale = 0;
227         else if (scale > 1) scale = 1;
228         int minfree_adj = Resources.getSystem().getInteger(
229                 com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAdjust);
230         int minfree_abs = Resources.getSystem().getInteger(
231                 com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAbsolute);
232         if (false) {
233             Slog.i("XXXXXX", "minfree_adj=" + minfree_adj + " minfree_abs=" + minfree_abs);
234         }
235 
236         final boolean is64bit = Build.SUPPORTED_64_BIT_ABIS.length > 0;
237 
238         for (int i=0; i<mOomAdj.length; i++) {
239             int low = mOomMinFreeLow[i];
240             int high = mOomMinFreeHigh[i];
241             if (is64bit) {
242                 // Increase the high min-free levels for cached processes for 64-bit
243                 if (i == 4) high = (high*3)/2;
244                 else if (i == 5) high = (high*7)/4;
245             }
246             mOomMinFree[i] = (int)(low + ((high-low)*scale));
247         }
248 
249         if (minfree_abs >= 0) {
250             for (int i=0; i<mOomAdj.length; i++) {
251                 mOomMinFree[i] = (int)((float)minfree_abs * mOomMinFree[i]
252                         / mOomMinFree[mOomAdj.length - 1]);
253             }
254         }
255 
256         if (minfree_adj != 0) {
257             for (int i=0; i<mOomAdj.length; i++) {
258                 mOomMinFree[i] += (int)((float)minfree_adj * mOomMinFree[i]
259                         / mOomMinFree[mOomAdj.length - 1]);
260                 if (mOomMinFree[i] < 0) {
261                     mOomMinFree[i] = 0;
262                 }
263             }
264         }
265 
266         // The maximum size we will restore a process from cached to background, when under
267         // memory duress, is 1/3 the size we have reserved for kernel caches and other overhead
268         // before killing background processes.
269         mCachedRestoreLevel = (getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024) / 3;
270 
271         // Ask the kernel to try to keep enough memory free to allocate 3 full
272         // screen 32bpp buffers without entering direct reclaim.
273         int reserve = displayWidth * displayHeight * 4 * 3 / 1024;
274         int reserve_adj = Resources.getSystem().getInteger(com.android.internal.R.integer.config_extraFreeKbytesAdjust);
275         int reserve_abs = Resources.getSystem().getInteger(com.android.internal.R.integer.config_extraFreeKbytesAbsolute);
276 
277         if (reserve_abs >= 0) {
278             reserve = reserve_abs;
279         }
280 
281         if (reserve_adj != 0) {
282             reserve += reserve_adj;
283             if (reserve < 0) {
284                 reserve = 0;
285             }
286         }
287 
288         if (write) {
289             ByteBuffer buf = ByteBuffer.allocate(4 * (2*mOomAdj.length + 1));
290             buf.putInt(LMK_TARGET);
291             for (int i=0; i<mOomAdj.length; i++) {
292                 buf.putInt((mOomMinFree[i]*1024)/PAGE_SIZE);
293                 buf.putInt(mOomAdj[i]);
294             }
295 
296             writeLmkd(buf);
297             SystemProperties.set("sys.sysctl.extra_free_kbytes", Integer.toString(reserve));
298         }
299         // GB: 2048,3072,4096,6144,7168,8192
300         // HC: 8192,10240,12288,14336,16384,20480
301     }
302 
computeEmptyProcessLimit(int totalProcessLimit)303     public static int computeEmptyProcessLimit(int totalProcessLimit) {
304         return totalProcessLimit/2;
305     }
306 
buildOomTag(String prefix, String space, int val, int base)307     private static String buildOomTag(String prefix, String space, int val, int base) {
308         if (val == base) {
309             if (space == null) return prefix;
310             return prefix + "  ";
311         }
312         return prefix + "+" + Integer.toString(val-base);
313     }
314 
makeOomAdjString(int setAdj)315     public static String makeOomAdjString(int setAdj) {
316         if (setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
317             return buildOomTag("cch", "  ", setAdj, ProcessList.CACHED_APP_MIN_ADJ);
318         } else if (setAdj >= ProcessList.SERVICE_B_ADJ) {
319             return buildOomTag("svcb ", null, setAdj, ProcessList.SERVICE_B_ADJ);
320         } else if (setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
321             return buildOomTag("prev ", null, setAdj, ProcessList.PREVIOUS_APP_ADJ);
322         } else if (setAdj >= ProcessList.HOME_APP_ADJ) {
323             return buildOomTag("home ", null, setAdj, ProcessList.HOME_APP_ADJ);
324         } else if (setAdj >= ProcessList.SERVICE_ADJ) {
325             return buildOomTag("svc  ", null, setAdj, ProcessList.SERVICE_ADJ);
326         } else if (setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
327             return buildOomTag("hvy  ", null, setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
328         } else if (setAdj >= ProcessList.BACKUP_APP_ADJ) {
329             return buildOomTag("bkup ", null, setAdj, ProcessList.BACKUP_APP_ADJ);
330         } else if (setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
331             return buildOomTag("prcp ", null, setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
332         } else if (setAdj >= ProcessList.VISIBLE_APP_ADJ) {
333             return buildOomTag("vis  ", null, setAdj, ProcessList.VISIBLE_APP_ADJ);
334         } else if (setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
335             return buildOomTag("fore ", null, setAdj, ProcessList.FOREGROUND_APP_ADJ);
336         } else if (setAdj >= ProcessList.PERSISTENT_SERVICE_ADJ) {
337             return buildOomTag("psvc ", null, setAdj, ProcessList.PERSISTENT_SERVICE_ADJ);
338         } else if (setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
339             return buildOomTag("pers ", null, setAdj, ProcessList.PERSISTENT_PROC_ADJ);
340         } else if (setAdj >= ProcessList.SYSTEM_ADJ) {
341             return buildOomTag("sys  ", null, setAdj, ProcessList.SYSTEM_ADJ);
342         } else if (setAdj >= ProcessList.NATIVE_ADJ) {
343             return buildOomTag("ntv  ", null, setAdj, ProcessList.NATIVE_ADJ);
344         } else {
345             return Integer.toString(setAdj);
346         }
347     }
348 
makeProcStateString(int curProcState)349     public static String makeProcStateString(int curProcState) {
350         String procState;
351         switch (curProcState) {
352             case ActivityManager.PROCESS_STATE_PERSISTENT:
353                 procState = "PER ";
354                 break;
355             case ActivityManager.PROCESS_STATE_PERSISTENT_UI:
356                 procState = "PERU";
357                 break;
358             case ActivityManager.PROCESS_STATE_TOP:
359                 procState = "TOP ";
360                 break;
361             case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
362                 procState = "BFGS";
363                 break;
364             case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
365                 procState = "FGS ";
366                 break;
367             case ActivityManager.PROCESS_STATE_TOP_SLEEPING:
368                 procState = "TPSL";
369                 break;
370             case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
371                 procState = "IMPF";
372                 break;
373             case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
374                 procState = "IMPB";
375                 break;
376             case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
377                 procState = "TRNB";
378                 break;
379             case ActivityManager.PROCESS_STATE_BACKUP:
380                 procState = "BKUP";
381                 break;
382             case ActivityManager.PROCESS_STATE_HEAVY_WEIGHT:
383                 procState = "HVY ";
384                 break;
385             case ActivityManager.PROCESS_STATE_SERVICE:
386                 procState = "SVC ";
387                 break;
388             case ActivityManager.PROCESS_STATE_RECEIVER:
389                 procState = "RCVR";
390                 break;
391             case ActivityManager.PROCESS_STATE_HOME:
392                 procState = "HOME";
393                 break;
394             case ActivityManager.PROCESS_STATE_LAST_ACTIVITY:
395                 procState = "LAST";
396                 break;
397             case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
398                 procState = "CAC ";
399                 break;
400             case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
401                 procState = "CACC";
402                 break;
403             case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
404                 procState = "CEM ";
405                 break;
406             case ActivityManager.PROCESS_STATE_NONEXISTENT:
407                 procState = "NONE";
408                 break;
409             default:
410                 procState = "??";
411                 break;
412         }
413         return procState;
414     }
415 
appendRamKb(StringBuilder sb, long ramKb)416     public static void appendRamKb(StringBuilder sb, long ramKb) {
417         for (int j=0, fact=10; j<6; j++, fact*=10) {
418             if (ramKb < fact) {
419                 sb.append(' ');
420             }
421         }
422         sb.append(ramKb);
423     }
424 
425     // How long after a state change that it is safe to collect PSS without it being dirty.
426     public static final int PSS_SAFE_TIME_FROM_STATE_CHANGE = 1000;
427 
428     // The minimum time interval after a state change it is safe to collect PSS.
429     public static final int PSS_MIN_TIME_FROM_STATE_CHANGE = 15*1000;
430 
431     // The maximum amount of time we want to go between PSS collections.
432     public static final int PSS_MAX_INTERVAL = 30*60*1000;
433 
434     // The minimum amount of time between successive PSS requests for *all* processes.
435     public static final int PSS_ALL_INTERVAL = 10*60*1000;
436 
437     // The minimum amount of time between successive PSS requests for a process.
438     private static final int PSS_SHORT_INTERVAL = 2*60*1000;
439 
440     // The amount of time until PSS when a process first becomes top.
441     private static final int PSS_FIRST_TOP_INTERVAL = 10*1000;
442 
443     // The amount of time until PSS when a process first goes into the background.
444     private static final int PSS_FIRST_BACKGROUND_INTERVAL = 20*1000;
445 
446     // The amount of time until PSS when a process first becomes cached.
447     private static final int PSS_FIRST_CACHED_INTERVAL = 30*1000;
448 
449     // The amount of time until PSS when an important process stays in the same state.
450     private static final int PSS_SAME_IMPORTANT_INTERVAL = 15*60*1000;
451 
452     // The amount of time until PSS when a service process stays in the same state.
453     private static final int PSS_SAME_SERVICE_INTERVAL = 20*60*1000;
454 
455     // The amount of time until PSS when a cached process stays in the same state.
456     private static final int PSS_SAME_CACHED_INTERVAL = 30*60*1000;
457 
458     // The minimum time interval after a state change it is safe to collect PSS.
459     public static final int PSS_TEST_MIN_TIME_FROM_STATE_CHANGE = 10*1000;
460 
461     // The amount of time during testing until PSS when a process first becomes top.
462     private static final int PSS_TEST_FIRST_TOP_INTERVAL = 3*1000;
463 
464     // The amount of time during testing until PSS when a process first goes into the background.
465     private static final int PSS_TEST_FIRST_BACKGROUND_INTERVAL = 5*1000;
466 
467     // The amount of time during testing until PSS when an important process stays in same state.
468     private static final int PSS_TEST_SAME_IMPORTANT_INTERVAL = 10*1000;
469 
470     // The amount of time during testing until PSS when a background process stays in same state.
471     private static final int PSS_TEST_SAME_BACKGROUND_INTERVAL = 15*1000;
472 
473     public static final int PROC_MEM_PERSISTENT = 0;
474     public static final int PROC_MEM_TOP = 1;
475     public static final int PROC_MEM_IMPORTANT = 2;
476     public static final int PROC_MEM_SERVICE = 3;
477     public static final int PROC_MEM_CACHED = 4;
478 
479     private static final int[] sProcStateToProcMem = new int[] {
480         PROC_MEM_PERSISTENT,            // ActivityManager.PROCESS_STATE_PERSISTENT
481         PROC_MEM_PERSISTENT,            // ActivityManager.PROCESS_STATE_PERSISTENT_UI
482         PROC_MEM_TOP,                   // ActivityManager.PROCESS_STATE_TOP
483         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
484         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
485         PROC_MEM_TOP,                   // ActivityManager.PROCESS_STATE_TOP_SLEEPING
486         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
487         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
488         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
489         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_BACKUP
490         PROC_MEM_IMPORTANT,             // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
491         PROC_MEM_SERVICE,               // ActivityManager.PROCESS_STATE_SERVICE
492         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_RECEIVER
493         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_HOME
494         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
495         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
496         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
497         PROC_MEM_CACHED,                // ActivityManager.PROCESS_STATE_CACHED_EMPTY
498     };
499 
500     private static final long[] sFirstAwakePssTimes = new long[] {
501         PSS_SHORT_INTERVAL,             // ActivityManager.PROCESS_STATE_PERSISTENT
502         PSS_SHORT_INTERVAL,             // ActivityManager.PROCESS_STATE_PERSISTENT_UI
503         PSS_FIRST_TOP_INTERVAL,         // ActivityManager.PROCESS_STATE_TOP
504         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
505         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
506         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_TOP_SLEEPING
507         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
508         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
509         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
510         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_BACKUP
511         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
512         PSS_FIRST_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_SERVICE
513         PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_RECEIVER
514         PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_HOME
515         PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
516         PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
517         PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
518         PSS_FIRST_CACHED_INTERVAL,      // ActivityManager.PROCESS_STATE_CACHED_EMPTY
519     };
520 
521     private static final long[] sSameAwakePssTimes = new long[] {
522         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_PERSISTENT
523         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_PERSISTENT_UI
524         PSS_SHORT_INTERVAL,             // ActivityManager.PROCESS_STATE_TOP
525         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
526         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
527         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_TOP_SLEEPING
528         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
529         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
530         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
531         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_BACKUP
532         PSS_SAME_IMPORTANT_INTERVAL,    // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
533         PSS_SAME_SERVICE_INTERVAL,      // ActivityManager.PROCESS_STATE_SERVICE
534         PSS_SAME_SERVICE_INTERVAL,      // ActivityManager.PROCESS_STATE_RECEIVER
535         PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_HOME
536         PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
537         PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
538         PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
539         PSS_SAME_CACHED_INTERVAL,       // ActivityManager.PROCESS_STATE_CACHED_EMPTY
540     };
541 
542     private static final long[] sTestFirstAwakePssTimes = new long[] {
543         PSS_TEST_FIRST_TOP_INTERVAL,        // ActivityManager.PROCESS_STATE_PERSISTENT
544         PSS_TEST_FIRST_TOP_INTERVAL,        // ActivityManager.PROCESS_STATE_PERSISTENT_UI
545         PSS_TEST_FIRST_TOP_INTERVAL,        // ActivityManager.PROCESS_STATE_TOP
546         PSS_FIRST_BACKGROUND_INTERVAL,      // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
547         PSS_FIRST_BACKGROUND_INTERVAL,      // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
548         PSS_FIRST_BACKGROUND_INTERVAL,      // ActivityManager.PROCESS_STATE_TOP_SLEEPING
549         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
550         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
551         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
552         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_BACKUP
553         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
554         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_SERVICE
555         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_RECEIVER
556         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_HOME
557         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
558         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
559         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
560         PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_EMPTY
561     };
562 
563     private static final long[] sTestSameAwakePssTimes = new long[] {
564         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_PERSISTENT
565         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_PERSISTENT_UI
566         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_TOP
567         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
568         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
569         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_TOP_SLEEPING
570         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
571         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
572         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
573         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_BACKUP
574         PSS_TEST_SAME_IMPORTANT_INTERVAL,   // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
575         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_SERVICE
576         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_RECEIVER
577         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_HOME
578         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
579         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
580         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
581         PSS_TEST_SAME_BACKGROUND_INTERVAL,  // ActivityManager.PROCESS_STATE_CACHED_EMPTY
582     };
583 
procStatesDifferForMem(int procState1, int procState2)584     public static boolean procStatesDifferForMem(int procState1, int procState2) {
585         return sProcStateToProcMem[procState1] != sProcStateToProcMem[procState2];
586     }
587 
minTimeFromStateChange(boolean test)588     public static long minTimeFromStateChange(boolean test) {
589         return test ? PSS_TEST_MIN_TIME_FROM_STATE_CHANGE : PSS_MIN_TIME_FROM_STATE_CHANGE;
590     }
591 
computeNextPssTime(int procState, boolean first, boolean test, boolean sleeping, long now)592     public static long computeNextPssTime(int procState, boolean first, boolean test,
593             boolean sleeping, long now) {
594         final long[] table = test
595                 ? (first
596                         ? sTestFirstAwakePssTimes
597                         : sTestSameAwakePssTimes)
598                 : (first
599                         ? sFirstAwakePssTimes
600                         : sSameAwakePssTimes);
601         return now + table[procState];
602     }
603 
getMemLevel(int adjustment)604     long getMemLevel(int adjustment) {
605         for (int i=0; i<mOomAdj.length; i++) {
606             if (adjustment <= mOomAdj[i]) {
607                 return mOomMinFree[i] * 1024;
608             }
609         }
610         return mOomMinFree[mOomAdj.length-1] * 1024;
611     }
612 
613     /**
614      * Return the maximum pss size in kb that we consider a process acceptable to
615      * restore from its cached state for running in the background when RAM is low.
616      */
getCachedRestoreThresholdKb()617     long getCachedRestoreThresholdKb() {
618         return mCachedRestoreLevel;
619     }
620 
621     /**
622      * Set the out-of-memory badness adjustment for a process.
623      *
624      * @param pid The process identifier to set.
625      * @param uid The uid of the app
626      * @param amt Adjustment value -- lmkd allows -16 to +15.
627      *
628      * {@hide}
629      */
setOomAdj(int pid, int uid, int amt)630     public static final void setOomAdj(int pid, int uid, int amt) {
631         if (amt == UNKNOWN_ADJ)
632             return;
633 
634         long start = SystemClock.elapsedRealtime();
635         ByteBuffer buf = ByteBuffer.allocate(4 * 4);
636         buf.putInt(LMK_PROCPRIO);
637         buf.putInt(pid);
638         buf.putInt(uid);
639         buf.putInt(amt);
640         writeLmkd(buf);
641         long now = SystemClock.elapsedRealtime();
642         if ((now-start) > 250) {
643             Slog.w("ActivityManager", "SLOW OOM ADJ: " + (now-start) + "ms for pid " + pid
644                     + " = " + amt);
645         }
646     }
647 
648     /*
649      * {@hide}
650      */
remove(int pid)651     public static final void remove(int pid) {
652         ByteBuffer buf = ByteBuffer.allocate(4 * 2);
653         buf.putInt(LMK_PROCREMOVE);
654         buf.putInt(pid);
655         writeLmkd(buf);
656     }
657 
openLmkdSocket()658     private static boolean openLmkdSocket() {
659         try {
660             sLmkdSocket = new LocalSocket(LocalSocket.SOCKET_SEQPACKET);
661             sLmkdSocket.connect(
662                 new LocalSocketAddress("lmkd",
663                         LocalSocketAddress.Namespace.RESERVED));
664             sLmkdOutputStream = sLmkdSocket.getOutputStream();
665         } catch (IOException ex) {
666             Slog.w(TAG, "lowmemorykiller daemon socket open failed");
667             sLmkdSocket = null;
668             return false;
669         }
670 
671         return true;
672     }
673 
writeLmkd(ByteBuffer buf)674     private static void writeLmkd(ByteBuffer buf) {
675 
676         for (int i = 0; i < 3; i++) {
677             if (sLmkdSocket == null) {
678                     if (openLmkdSocket() == false) {
679                         try {
680                             Thread.sleep(1000);
681                         } catch (InterruptedException ie) {
682                         }
683                         continue;
684                     }
685             }
686 
687             try {
688                 sLmkdOutputStream.write(buf.array(), 0, buf.position());
689                 return;
690             } catch (IOException ex) {
691                 Slog.w(TAG, "Error writing to lowmemorykiller socket");
692 
693                 try {
694                     sLmkdSocket.close();
695                 } catch (IOException ex2) {
696                 }
697 
698                 sLmkdSocket = null;
699             }
700         }
701     }
702 }
703