ProcessList.java revision b12e1354f25f04e9c9a71da76c6fca858b7d39d0
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
17package com.android.server.am;
18
19import java.io.FileOutputStream;
20import java.io.IOException;
21
22import com.android.internal.util.MemInfoReader;
23import com.android.server.wm.WindowManagerService;
24
25import android.graphics.Point;
26import android.util.Slog;
27import android.view.Display;
28
29/**
30 * Activity manager code dealing with processes.
31 */
32class ProcessList {
33    // The minimum time we allow between crashes, for us to consider this
34    // application to be bad and stop and its services and reject broadcasts.
35    static final int MIN_CRASH_INTERVAL = 60*1000;
36
37    // OOM adjustments for processes in various states:
38
39    // This is a process only hosting activities that are not visible,
40    // so it can be killed without any disruption.
41    static final int HIDDEN_APP_MAX_ADJ = 15;
42    static int HIDDEN_APP_MIN_ADJ = 9;
43
44    // The B list of SERVICE_ADJ -- these are the old and decrepit
45    // services that aren't as shiny and interesting as the ones in the A list.
46    static final int SERVICE_B_ADJ = 8;
47
48    // This is the process of the previous application that the user was in.
49    // This process is kept above other things, because it is very common to
50    // switch back to the previous app.  This is important both for recent
51    // task switch (toggling between the two top recent apps) as well as normal
52    // UI flow such as clicking on a URI in the e-mail app to view in the browser,
53    // and then pressing back to return to e-mail.
54    static final int PREVIOUS_APP_ADJ = 7;
55
56    // This is a process holding the home application -- we want to try
57    // avoiding killing it, even if it would normally be in the background,
58    // because the user interacts with it so much.
59    static final int HOME_APP_ADJ = 6;
60
61    // This is a process holding an application service -- killing it will not
62    // have much of an impact as far as the user is concerned.
63    static final int SERVICE_ADJ = 5;
64
65    // This is a process currently hosting a backup operation.  Killing it
66    // is not entirely fatal but is generally a bad idea.
67    static final int BACKUP_APP_ADJ = 4;
68
69    // This is a process with a heavy-weight application.  It is in the
70    // background, but we want to try to avoid killing it.  Value set in
71    // system/rootdir/init.rc on startup.
72    static final int HEAVY_WEIGHT_APP_ADJ = 3;
73
74    // This is a process only hosting components that are perceptible to the
75    // user, and we really want to avoid killing them, but they are not
76    // immediately visible. An example is background music playback.
77    static final int PERCEPTIBLE_APP_ADJ = 2;
78
79    // This is a process only hosting activities that are visible to the
80    // user, so we'd prefer they don't disappear.
81    static final int VISIBLE_APP_ADJ = 1;
82
83    // This is the process running the current foreground app.  We'd really
84    // rather not kill it!
85    static final int FOREGROUND_APP_ADJ = 0;
86
87    // This is a system persistent process, such as telephony.  Definitely
88    // don't want to kill it, but doing so is not completely fatal.
89    static final int PERSISTENT_PROC_ADJ = -12;
90
91    // The system process runs at the default adjustment.
92    static final int SYSTEM_ADJ = -16;
93
94    // Memory pages are 4K.
95    static final int PAGE_SIZE = 4*1024;
96
97    // The minimum number of hidden apps we want to be able to keep around,
98    // without empty apps being able to push them out of memory.
99    static final int MIN_HIDDEN_APPS = 2;
100
101    // The maximum number of hidden processes we will keep around before
102    // killing them; this is just a control to not let us go too crazy with
103    // keeping around processes on devices with large amounts of RAM.
104    static final int MAX_HIDDEN_APPS = 24;
105
106    // We allow empty processes to stick around for at most 30 minutes.
107    static final long MAX_EMPTY_TIME = 30*60*1000;
108
109    // The number of hidden at which we don't consider it necessary to do
110    // memory trimming.
111    static final int TRIM_HIDDEN_APPS = 3;
112
113    // The number of empty apps at which we don't consider it necessary to do
114    // memory trimming.
115    static final int TRIM_EMPTY_APPS = 3;
116
117    // Threshold of number of hidden+empty where we consider memory critical.
118    static final int TRIM_CRITICAL_THRESHOLD = 3;
119
120    // Threshold of number of hidden+empty where we consider memory critical.
121    static final int TRIM_LOW_THRESHOLD = 5;
122
123    // We put empty content processes after any hidden processes that have
124    // been idle for less than 15 seconds.
125    static final long CONTENT_APP_IDLE_OFFSET = 15*1000;
126
127    // We put empty content processes after any hidden processes that have
128    // been idle for less than 120 seconds.
129    static final long EMPTY_APP_IDLE_OFFSET = 120*1000;
130
131    // These are the various interesting memory levels that we will give to
132    // the OOM killer.  Note that the OOM killer only supports 6 slots, so we
133    // can't give it a different value for every possible kind of process.
134    private final int[] mOomAdj = new int[] {
135            FOREGROUND_APP_ADJ, VISIBLE_APP_ADJ, PERCEPTIBLE_APP_ADJ,
136            BACKUP_APP_ADJ, HIDDEN_APP_MIN_ADJ, HIDDEN_APP_MAX_ADJ
137    };
138    // These are the low-end OOM level limits.  This is appropriate for an
139    // HVGA or smaller phone with less than 512MB.  Values are in KB.
140    private final long[] mOomMinFreeLow = new long[] {
141            8192, 12288, 16384,
142            24576, 28672, 32768
143    };
144    // These are the high-end OOM level limits.  This is appropriate for a
145    // 1280x800 or larger screen with around 1GB RAM.  Values are in KB.
146    private final long[] mOomMinFreeHigh = new long[] {
147            32768, 40960, 49152,
148            57344, 65536, 81920
149    };
150    // The actual OOM killer memory levels we are using.
151    private final long[] mOomMinFree = new long[mOomAdj.length];
152
153    private final long mTotalMemMb;
154
155    private boolean mHaveDisplaySize;
156
157    ProcessList() {
158        MemInfoReader minfo = new MemInfoReader();
159        minfo.readMemInfo();
160        mTotalMemMb = minfo.getTotalSize()/(1024*1024);
161        updateOomLevels(0, 0, false);
162    }
163
164    void applyDisplaySize(WindowManagerService wm) {
165        if (!mHaveDisplaySize) {
166            Point p = new Point();
167            wm.getInitialDisplaySize(Display.DEFAULT_DISPLAY, p);
168            if (p.x != 0 && p.y != 0) {
169                updateOomLevels(p.x, p.y, true);
170                mHaveDisplaySize = true;
171            }
172        }
173    }
174
175    private void updateOomLevels(int displayWidth, int displayHeight, boolean write) {
176        // Scale buckets from avail memory: at 300MB we use the lowest values to
177        // 700MB or more for the top values.
178        float scaleMem = ((float)(mTotalMemMb-300))/(700-300);
179
180        // Scale buckets from screen size.
181        int minSize = 320*480;  //  153600
182        int maxSize = 1280*800; // 1024000  230400 870400  .264
183        float scaleDisp = ((float)(displayWidth*displayHeight)-minSize)/(maxSize-minSize);
184        //Slog.i("XXXXXX", "scaleDisp=" + scaleDisp + " dw=" + displayWidth + " dh=" + displayHeight);
185
186        StringBuilder adjString = new StringBuilder();
187        StringBuilder memString = new StringBuilder();
188
189        float scale = scaleMem > scaleDisp ? scaleMem : scaleDisp;
190        if (scale < 0) scale = 0;
191        else if (scale > 1) scale = 1;
192        for (int i=0; i<mOomAdj.length; i++) {
193            long low = mOomMinFreeLow[i];
194            long high = mOomMinFreeHigh[i];
195            mOomMinFree[i] = (long)(low + ((high-low)*scale));
196
197            if (i > 0) {
198                adjString.append(',');
199                memString.append(',');
200            }
201            adjString.append(mOomAdj[i]);
202            memString.append((mOomMinFree[i]*1024)/PAGE_SIZE);
203        }
204
205        //Slog.i("XXXXXXX", "******************************* MINFREE: " + memString);
206        if (write) {
207            writeFile("/sys/module/lowmemorykiller/parameters/adj", adjString.toString());
208            writeFile("/sys/module/lowmemorykiller/parameters/minfree", memString.toString());
209        }
210        // GB: 2048,3072,4096,6144,7168,8192
211        // HC: 8192,10240,12288,14336,16384,20480
212    }
213
214    long getMemLevel(int adjustment) {
215        for (int i=0; i<mOomAdj.length; i++) {
216            if (adjustment <= mOomAdj[i]) {
217                return mOomMinFree[i] * 1024;
218            }
219        }
220        return mOomMinFree[mOomAdj.length-1] * 1024;
221    }
222
223    private void writeFile(String path, String data) {
224        FileOutputStream fos = null;
225        try {
226            fos = new FileOutputStream(path);
227            fos.write(data.getBytes());
228        } catch (IOException e) {
229            Slog.w(ActivityManagerService.TAG, "Unable to write " + path);
230        } finally {
231            if (fos != null) {
232                try {
233                    fos.close();
234                } catch (IOException e) {
235                }
236            }
237        }
238    }
239}
240