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