blob: 1a635a9a14a02c7b96590447453d3ad42e283dc0 [file] [log] [blame]
Dianne Hackborn7d608422011-08-07 16:24:18 -07001/*
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
Dianne Hackborn7d608422011-08-07 16:24:18 -070019import 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;
Dianne Hackborn7d608422011-08-07 16:24:18 -070026import android.util.Slog;
Craig Mautner59c00972012-07-30 12:10:24 -070027import android.view.Display;
Dianne Hackborn7d608422011-08-07 16:24:18 -070028
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
Dianne Hackborn7d608422011-08-07 16:24:18 -070039 // This is a process only hosting activities that are not visible,
Dianne Hackborne02c88a2011-10-28 13:58:15 -070040 // so it can be killed without any disruption.
Dianne Hackborn7d608422011-08-07 16:24:18 -070041 static final int HIDDEN_APP_MAX_ADJ = 15;
Dianne Hackbornf35fe232011-11-01 19:25:20 -070042 static int HIDDEN_APP_MIN_ADJ = 9;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070043
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.
Dianne Hackbornf35fe232011-11-01 19:25:20 -070046 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;
Dianne Hackborn7d608422011-08-07 16:24:18 -070055
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
Dianne Hackborne02c88a2011-10-28 13:58:15 -070061 // 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;
Dianne Hackborn7d608422011-08-07 16:24:18 -070064
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
Dianne Hackborne02c88a2011-10-28 13:58:15 -070076 // immediately visible. An example is background music playback.
Dianne Hackborn7d608422011-08-07 16:24:18 -070077 static final int PERCEPTIBLE_APP_ADJ = 2;
78
79 // This is a process only hosting activities that are visible to the
Dianne Hackborne02c88a2011-10-28 13:58:15 -070080 // user, so we'd prefer they don't disappear.
Dianne Hackborn7d608422011-08-07 16:24:18 -070081 static final int VISIBLE_APP_ADJ = 1;
82
83 // This is the process running the current foreground app. We'd really
Dianne Hackborne02c88a2011-10-28 13:58:15 -070084 // rather not kill it!
Dianne Hackborn7d608422011-08-07 16:24:18 -070085 static final int FOREGROUND_APP_ADJ = 0;
86
Dianne Hackborne02c88a2011-10-28 13:58:15 -070087 // This is a system persistent process, such as telephony. Definitely
Dianne Hackborn7d608422011-08-07 16:24:18 -070088 // don't want to kill it, but doing so is not completely fatal.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070089 static final int PERSISTENT_PROC_ADJ = -12;
Dianne Hackborn7d608422011-08-07 16:24:18 -070090
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.
Dianne Hackbornb12e1352012-09-26 11:39:20 -0700104 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;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700122
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,
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700136 BACKUP_APP_ADJ, HIDDEN_APP_MIN_ADJ, HIDDEN_APP_MAX_ADJ
Dianne Hackborn7d608422011-08-07 16:24:18 -0700137 };
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[] {
Ben Chengb5cda422013-03-27 17:36:13 -0700147 49152, 61440, 73728,
148 86016, 98304, 122880
Dianne Hackborn7d608422011-08-07 16:24:18 -0700149 };
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();
Craig Mautner59c00972012-07-30 12:10:24 -0700167 wm.getInitialDisplaySize(Display.DEFAULT_DISPLAY, p);
Dianne Hackborn7d608422011-08-07 16:24:18 -0700168 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);
Dianne Hackborn295e3c22011-08-25 13:19:08 -0700184 //Slog.i("XXXXXX", "scaleDisp=" + scaleDisp + " dw=" + displayWidth + " dh=" + displayHeight);
Dianne Hackborn7d608422011-08-07 16:24:18 -0700185
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}