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