blob: 40effff77166bb73dd199bd7e744fc64a10418a6 [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
Wale Ogunwalee23149f2015-03-06 15:39:44 -080019import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
20import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
21
Dianne Hackborn7d608422011-08-07 16:24:18 -070022import java.io.IOException;
Todd Poynorbfdd6232013-07-10 19:15:07 -070023import java.io.OutputStream;
24import java.nio.ByteBuffer;
Dianne Hackborn7d608422011-08-07 16:24:18 -070025
Dianne Hackborn8e692572013-09-10 19:06:15 -070026import android.app.ActivityManager;
Dianne Hackborn9d52f792014-09-11 17:46:06 -070027import android.os.Build;
Dianne Hackbornecf1cda2014-08-28 16:58:28 -070028import android.os.SystemClock;
Dianne Hackborn7d608422011-08-07 16:24:18 -070029import com.android.internal.util.MemInfoReader;
30import com.android.server.wm.WindowManagerService;
31
Colin Crossfcdad6f2013-07-25 15:04:40 -070032import android.content.res.Resources;
Dianne Hackborn7d608422011-08-07 16:24:18 -070033import android.graphics.Point;
Colin Cross59d80a52013-07-25 10:45:05 -070034import android.os.SystemProperties;
Todd Poynorbfdd6232013-07-10 19:15:07 -070035import android.net.LocalSocketAddress;
36import android.net.LocalSocket;
Dianne Hackborn7d608422011-08-07 16:24:18 -070037import android.util.Slog;
Craig Mautner59c00972012-07-30 12:10:24 -070038import android.view.Display;
Dianne Hackborn7d608422011-08-07 16:24:18 -070039
40/**
41 * Activity manager code dealing with processes.
42 */
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -070043final class ProcessList {
Wale Ogunwalee23149f2015-03-06 15:39:44 -080044 private static final String TAG = TAG_WITH_CLASS_NAME ? "ProcessList" : TAG_AM;
45
Dianne Hackborn7d608422011-08-07 16:24:18 -070046 // 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
Chong Zhangfdcc4d42015-10-14 16:50:12 -070052 // Uninitialized value for any major or minor adj fields
53 static final int INVALID_ADJ = -10000;
54
Dianne Hackbornc8230512013-07-13 21:32:12 -070055 // 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.)
Chong Zhangfdcc4d42015-10-14 16:50:12 -070058 static final int UNKNOWN_ADJ = 1001;
Dianne Hackbornc8230512013-07-13 21:32:12 -070059
Dianne Hackborn7d608422011-08-07 16:24:18 -070060 // This is a process only hosting activities that are not visible,
Dianne Hackborne02c88a2011-10-28 13:58:15 -070061 // so it can be killed without any disruption.
Chong Zhangfdcc4d42015-10-14 16:50:12 -070062 static final int CACHED_APP_MAX_ADJ = 906;
63 static final int CACHED_APP_MIN_ADJ = 900;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070064
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.
Chong Zhangfdcc4d42015-10-14 16:50:12 -070067 static final int SERVICE_B_ADJ = 800;
Dianne Hackbornf35fe232011-11-01 19:25:20 -070068
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.
Chong Zhangfdcc4d42015-10-14 16:50:12 -070075 static final int PREVIOUS_APP_ADJ = 700;
Dianne Hackborn7d608422011-08-07 16:24:18 -070076
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.
Chong Zhangfdcc4d42015-10-14 16:50:12 -070080 static final int HOME_APP_ADJ = 600;
Dianne Hackborn7d608422011-08-07 16:24:18 -070081
Dianne Hackborne02c88a2011-10-28 13:58:15 -070082 // 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.
Chong Zhangfdcc4d42015-10-14 16:50:12 -070084 static final int SERVICE_ADJ = 500;
Dianne Hackborn7d608422011-08-07 16:24:18 -070085
Dianne Hackborn7d608422011-08-07 16:24:18 -070086 // 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.
Chong Zhangfdcc4d42015-10-14 16:50:12 -070089 static final int HEAVY_WEIGHT_APP_ADJ = 400;
Dianne Hackbornc8230512013-07-13 21:32:12 -070090
91 // This is a process currently hosting a backup operation. Killing it
92 // is not entirely fatal but is generally a bad idea.
Chong Zhangfdcc4d42015-10-14 16:50:12 -070093 static final int BACKUP_APP_ADJ = 300;
Dianne Hackborn7d608422011-08-07 16:24:18 -070094
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
Dianne Hackborne02c88a2011-10-28 13:58:15 -070097 // immediately visible. An example is background music playback.
Chong Zhangfdcc4d42015-10-14 16:50:12 -070098 static final int PERCEPTIBLE_APP_ADJ = 200;
Dianne Hackborn7d608422011-08-07 16:24:18 -070099
100 // This is a process only hosting activities that are visible to the
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700101 // user, so we'd prefer they don't disappear.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700102 static final int VISIBLE_APP_ADJ = 100;
103 static final int VISIBLE_APP_LAYER_MAX = PERCEPTIBLE_APP_ADJ - VISIBLE_APP_ADJ - 1;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700104
105 // This is the process running the current foreground app. We'd really
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700106 // rather not kill it!
Dianne Hackborn7d608422011-08-07 16:24:18 -0700107 static final int FOREGROUND_APP_ADJ = 0;
108
Dianne Hackbornce09f5a2014-10-10 15:03:13 -0700109 // This is a process that the system or a persistent process has bound to,
110 // and indicated it is important.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700111 static final int PERSISTENT_SERVICE_ADJ = -700;
Dianne Hackbornce09f5a2014-10-10 15:03:13 -0700112
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700113 // This is a system persistent process, such as telephony. Definitely
Dianne Hackborn7d608422011-08-07 16:24:18 -0700114 // don't want to kill it, but doing so is not completely fatal.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700115 static final int PERSISTENT_PROC_ADJ = -800;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700116
117 // The system process runs at the default adjustment.
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700118 static final int SYSTEM_ADJ = -900;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700119
Dianne Hackborn8e692572013-09-10 19:06:15 -0700120 // 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).
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700122 static final int NATIVE_ADJ = -1000;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700123
Dianne Hackborn7d608422011-08-07 16:24:18 -0700124 // Memory pages are 4K.
125 static final int PAGE_SIZE = 4*1024;
126
Dianne Hackborna49ad092016-03-03 13:39:10 -0800127 // 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;
Tim Murray33eb07f2016-06-10 10:03:20 -0700133 // 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;
Dianne Hackborna49ad092016-03-03 13:39:10 -0800136
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -0700137 // The minimum number of cached apps we want to be able to keep around,
Dianne Hackborn7d608422011-08-07 16:24:18 -0700138 // without empty apps being able to push them out of memory.
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -0700139 static final int MIN_CACHED_APPS = 2;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700140
Dianne Hackbornb12e1352012-09-26 11:39:20 -0700141 // We allow empty processes to stick around for at most 30 minutes.
142 static final long MAX_EMPTY_TIME = 30*60*1000;
143
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -0700144 // Threshold of number of cached+empty where we consider memory critical.
Dianne Hackbornb12e1352012-09-26 11:39:20 -0700145 static final int TRIM_CRITICAL_THRESHOLD = 3;
146
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -0700147 // Threshold of number of cached+empty where we consider memory critical.
Dianne Hackbornb12e1352012-09-26 11:39:20 -0700148 static final int TRIM_LOW_THRESHOLD = 5;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700149
Todd Poynorbfdd6232013-07-10 19:15:07 -0700150 // 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)
Chong Zhangfdcc4d42015-10-14 16:50:12 -0700154 // LMK_PROCPRIO <pid> <uid> <prio>
Todd Poynorbfdd6232013-07-10 19:15:07 -0700155 // 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
Dianne Hackborn7d608422011-08-07 16:24:18 -0700160 // 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,
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -0700165 BACKUP_APP_ADJ, CACHED_APP_MIN_ADJ, CACHED_APP_MAX_ADJ
Dianne Hackborn7d608422011-08-07 16:24:18 -0700166 };
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.
Todd Poynorbfdd6232013-07-10 19:15:07 -0700169 private final int[] mOomMinFreeLow = new int[] {
Dianne Hackborn3f16dd42014-10-02 17:21:27 -0700170 12288, 18432, 24576,
171 36864, 43008, 49152
Dianne Hackborn7d608422011-08-07 16:24:18 -0700172 };
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.
Todd Poynorbfdd6232013-07-10 19:15:07 -0700175 private final int[] mOomMinFreeHigh = new int[] {
Dianne Hackborn3f16dd42014-10-02 17:21:27 -0700176 73728, 92160, 110592,
Dianne Hackborn824aeab2014-11-25 17:26:36 -0800177 129024, 147456, 184320
Dianne Hackborn7d608422011-08-07 16:24:18 -0700178 };
179 // The actual OOM killer memory levels we are using.
Todd Poynorbfdd6232013-07-10 19:15:07 -0700180 private final int[] mOomMinFree = new int[mOomAdj.length];
Dianne Hackborn7d608422011-08-07 16:24:18 -0700181
182 private final long mTotalMemMb;
183
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700184 private long mCachedRestoreLevel;
185
Dianne Hackborn7d608422011-08-07 16:24:18 -0700186 private boolean mHaveDisplaySize;
187
Todd Poynorbfdd6232013-07-10 19:15:07 -0700188 private static LocalSocket sLmkdSocket;
189 private static OutputStream sLmkdOutputStream;
190
Dianne Hackborn7d608422011-08-07 16:24:18 -0700191 ProcessList() {
192 MemInfoReader minfo = new MemInfoReader();
193 minfo.readMemInfo();
194 mTotalMemMb = minfo.getTotalSize()/(1024*1024);
195 updateOomLevels(0, 0, false);
196 }
197
198 void applyDisplaySize(WindowManagerService wm) {
199 if (!mHaveDisplaySize) {
200 Point p = new Point();
Andrii Kulian1e32e022016-09-16 15:29:34 -0700201 // TODO(multi-display): Compute based on sum of all connected displays' resolutions.
Colin Cross637dbfc2013-07-18 17:15:15 -0700202 wm.getBaseDisplaySize(Display.DEFAULT_DISPLAY, p);
Dianne Hackborn7d608422011-08-07 16:24:18 -0700203 if (p.x != 0 && p.y != 0) {
204 updateOomLevels(p.x, p.y, true);
205 mHaveDisplaySize = true;
206 }
207 }
208 }
209
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.
Dianne Hackborn824aeab2014-11-25 17:26:36 -0800213 float scaleMem = ((float)(mTotalMemMb-350))/(700-350);
Dianne Hackborn7d608422011-08-07 16:24:18 -0700214
215 // Scale buckets from screen size.
Dianne Hackborn635a6d52013-07-29 17:15:38 -0700216 int minSize = 480*800; // 384000
Dianne Hackborn7d608422011-08-07 16:24:18 -0700217 int maxSize = 1280*800; // 1024000 230400 870400 .264
218 float scaleDisp = ((float)(displayWidth*displayHeight)-minSize)/(maxSize-minSize);
Dianne Hackborn635a6d52013-07-29 17:15:38 -0700219 if (false) {
220 Slog.i("XXXXXX", "scaleMem=" + scaleMem);
221 Slog.i("XXXXXX", "scaleDisp=" + scaleDisp + " dw=" + displayWidth
222 + " dh=" + displayHeight);
223 }
Dianne Hackborn7d608422011-08-07 16:24:18 -0700224
Dianne Hackborn7d608422011-08-07 16:24:18 -0700225 float scale = scaleMem > scaleDisp ? scaleMem : scaleDisp;
226 if (scale < 0) scale = 0;
227 else if (scale > 1) scale = 1;
Dianne Hackborn635a6d52013-07-29 17:15:38 -0700228 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 }
Colin Crossfcdad6f2013-07-25 15:04:40 -0700235
Dianne Hackbornc478cf52015-01-05 16:05:05 -0800236 final boolean is64bit = Build.SUPPORTED_64_BIT_ABIS.length > 0;
Dianne Hackborn9d52f792014-09-11 17:46:06 -0700237
Dianne Hackborn7d608422011-08-07 16:24:18 -0700238 for (int i=0; i<mOomAdj.length; i++) {
Todd Poynorbfdd6232013-07-10 19:15:07 -0700239 int low = mOomMinFreeLow[i];
240 int high = mOomMinFreeHigh[i];
Dianne Hackbornc478cf52015-01-05 16:05:05 -0800241 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 }
Todd Poynorbfdd6232013-07-10 19:15:07 -0700246 mOomMinFree[i] = (int)(low + ((high-low)*scale));
Colin Crossfcdad6f2013-07-25 15:04:40 -0700247 }
Dianne Hackborn7d608422011-08-07 16:24:18 -0700248
Colin Crossfcdad6f2013-07-25 15:04:40 -0700249 if (minfree_abs >= 0) {
250 for (int i=0; i<mOomAdj.length; i++) {
Dianne Hackborn9d52f792014-09-11 17:46:06 -0700251 mOomMinFree[i] = (int)((float)minfree_abs * mOomMinFree[i]
252 / mOomMinFree[mOomAdj.length - 1]);
Colin Crossfcdad6f2013-07-25 15:04:40 -0700253 }
254 }
255
256 if (minfree_adj != 0) {
257 for (int i=0; i<mOomAdj.length; i++) {
Dianne Hackborn9d52f792014-09-11 17:46:06 -0700258 mOomMinFree[i] += (int)((float)minfree_adj * mOomMinFree[i]
259 / mOomMinFree[mOomAdj.length - 1]);
Colin Crossfcdad6f2013-07-25 15:04:40 -0700260 if (mOomMinFree[i] < 0) {
261 mOomMinFree[i] = 0;
262 }
263 }
264 }
265
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700266 // 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
Colin Cross59d80a52013-07-25 10:45:05 -0700271 // 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
Dianne Hackborn7d608422011-08-07 16:24:18 -0700288 if (write) {
Todd Poynorbfdd6232013-07-10 19:15:07 -0700289 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);
Colin Cross59d80a52013-07-25 10:45:05 -0700297 SystemProperties.set("sys.sysctl.extra_free_kbytes", Integer.toString(reserve));
Dianne Hackborn7d608422011-08-07 16:24:18 -0700298 }
299 // GB: 2048,3072,4096,6144,7168,8192
300 // HC: 8192,10240,12288,14336,16384,20480
301 }
302
Dianne Hackborn2286cdc2013-07-01 19:10:06 -0700303 public static int computeEmptyProcessLimit(int totalProcessLimit) {
Dianne Hackborn465fa392014-09-14 14:21:18 -0700304 return totalProcessLimit/2;
Dianne Hackborn2286cdc2013-07-01 19:10:06 -0700305 }
306
Dianne Hackborn8e692572013-09-10 19:06:15 -0700307 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
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);
Dianne Hackbornce09f5a2014-10-10 15:03:13 -0700336 } else if (setAdj >= ProcessList.PERSISTENT_SERVICE_ADJ) {
337 return buildOomTag("psvc ", null, setAdj, ProcessList.PERSISTENT_SERVICE_ADJ);
Dianne Hackborn8e692572013-09-10 19:06:15 -0700338 } 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
Dianne Hackborn8e692572013-09-10 19:06:15 -0700349 public static String makeProcStateString(int curProcState) {
350 String procState;
351 switch (curProcState) {
Dianne Hackborn8e692572013-09-10 19:06:15 -0700352 case ActivityManager.PROCESS_STATE_PERSISTENT:
353 procState = "P ";
354 break;
355 case ActivityManager.PROCESS_STATE_PERSISTENT_UI:
356 procState = "PU";
357 break;
358 case ActivityManager.PROCESS_STATE_TOP:
359 procState = "T ";
360 break;
Dianne Hackbornab4bb9d2015-06-05 18:08:37 -0700361 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
362 procState = "SB";
363 break;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700364 case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
Dianne Hackbornab4bb9d2015-06-05 18:08:37 -0700365 procState = "SF";
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700366 break;
367 case ActivityManager.PROCESS_STATE_TOP_SLEEPING:
368 procState = "TS";
369 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700370 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
371 procState = "IF";
372 break;
373 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
374 procState = "IB";
375 break;
376 case ActivityManager.PROCESS_STATE_BACKUP:
377 procState = "BU";
378 break;
379 case ActivityManager.PROCESS_STATE_HEAVY_WEIGHT:
380 procState = "HW";
381 break;
382 case ActivityManager.PROCESS_STATE_SERVICE:
383 procState = "S ";
384 break;
385 case ActivityManager.PROCESS_STATE_RECEIVER:
386 procState = "R ";
387 break;
388 case ActivityManager.PROCESS_STATE_HOME:
389 procState = "HO";
390 break;
391 case ActivityManager.PROCESS_STATE_LAST_ACTIVITY:
392 procState = "LA";
393 break;
394 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
395 procState = "CA";
396 break;
397 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
398 procState = "Ca";
399 break;
400 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
401 procState = "CE";
402 break;
Dianne Hackborn5614bf52016-11-07 17:26:41 -0800403 case ActivityManager.PROCESS_STATE_NONEXISTENT:
404 procState = "N ";
405 break;
Dianne Hackborn8e692572013-09-10 19:06:15 -0700406 default:
407 procState = "??";
408 break;
409 }
410 return procState;
411 }
412
413 public static void appendRamKb(StringBuilder sb, long ramKb) {
414 for (int j=0, fact=10; j<6; j++, fact*=10) {
415 if (ramKb < fact) {
416 sb.append(' ');
417 }
418 }
419 sb.append(ramKb);
420 }
421
Dianne Hackbornae6cc8a2014-12-10 10:33:27 -0800422 // How long after a state change that it is safe to collect PSS without it being dirty.
423 public static final int PSS_SAFE_TIME_FROM_STATE_CHANGE = 1000;
424
425 // The minimum time interval after a state change it is safe to collect PSS.
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700426 public static final int PSS_MIN_TIME_FROM_STATE_CHANGE = 15*1000;
427
428 // The maximum amount of time we want to go between PSS collections.
429 public static final int PSS_MAX_INTERVAL = 30*60*1000;
430
431 // The minimum amount of time between successive PSS requests for *all* processes.
432 public static final int PSS_ALL_INTERVAL = 10*60*1000;
433
434 // The minimum amount of time between successive PSS requests for a process.
435 private static final int PSS_SHORT_INTERVAL = 2*60*1000;
436
437 // The amount of time until PSS when a process first becomes top.
438 private static final int PSS_FIRST_TOP_INTERVAL = 10*1000;
439
440 // The amount of time until PSS when a process first goes into the background.
441 private static final int PSS_FIRST_BACKGROUND_INTERVAL = 20*1000;
442
443 // The amount of time until PSS when a process first becomes cached.
444 private static final int PSS_FIRST_CACHED_INTERVAL = 30*1000;
445
446 // The amount of time until PSS when an important process stays in the same state.
447 private static final int PSS_SAME_IMPORTANT_INTERVAL = 15*60*1000;
448
449 // The amount of time until PSS when a service process stays in the same state.
450 private static final int PSS_SAME_SERVICE_INTERVAL = 20*60*1000;
451
452 // The amount of time until PSS when a cached process stays in the same state.
453 private static final int PSS_SAME_CACHED_INTERVAL = 30*60*1000;
454
Dianne Hackbornae6cc8a2014-12-10 10:33:27 -0800455 // The minimum time interval after a state change it is safe to collect PSS.
456 public static final int PSS_TEST_MIN_TIME_FROM_STATE_CHANGE = 10*1000;
457
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -0800458 // The amount of time during testing until PSS when a process first becomes top.
459 private static final int PSS_TEST_FIRST_TOP_INTERVAL = 3*1000;
460
461 // The amount of time during testing until PSS when a process first goes into the background.
462 private static final int PSS_TEST_FIRST_BACKGROUND_INTERVAL = 5*1000;
463
464 // The amount of time during testing until PSS when an important process stays in same state.
465 private static final int PSS_TEST_SAME_IMPORTANT_INTERVAL = 10*1000;
466
467 // The amount of time during testing until PSS when a background process stays in same state.
468 private static final int PSS_TEST_SAME_BACKGROUND_INTERVAL = 15*1000;
469
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700470 public static final int PROC_MEM_PERSISTENT = 0;
471 public static final int PROC_MEM_TOP = 1;
472 public static final int PROC_MEM_IMPORTANT = 2;
473 public static final int PROC_MEM_SERVICE = 3;
474 public static final int PROC_MEM_CACHED = 4;
475
476 private static final int[] sProcStateToProcMem = new int[] {
477 PROC_MEM_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT
478 PROC_MEM_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT_UI
479 PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_TOP
Dianne Hackbornab4bb9d2015-06-05 18:08:37 -0700480 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700481 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
482 PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_TOP_SLEEPING
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700483 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
484 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
485 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_BACKUP
486 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
487 PROC_MEM_SERVICE, // ActivityManager.PROCESS_STATE_SERVICE
488 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_RECEIVER
489 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_HOME
490 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
491 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
492 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
493 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_EMPTY
494 };
495
496 private static final long[] sFirstAwakePssTimes = new long[] {
497 PSS_SHORT_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT
498 PSS_SHORT_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT_UI
499 PSS_FIRST_TOP_INTERVAL, // ActivityManager.PROCESS_STATE_TOP
Dianne Hackbornab4bb9d2015-06-05 18:08:37 -0700500 PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700501 PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
502 PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_TOP_SLEEPING
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700503 PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
504 PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
505 PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_BACKUP
506 PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
507 PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_SERVICE
508 PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_RECEIVER
509 PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_HOME
510 PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
511 PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
512 PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
513 PSS_FIRST_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_EMPTY
514 };
515
516 private static final long[] sSameAwakePssTimes = new long[] {
517 PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT
518 PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT_UI
519 PSS_SHORT_INTERVAL, // ActivityManager.PROCESS_STATE_TOP
Dianne Hackbornab4bb9d2015-06-05 18:08:37 -0700520 PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700521 PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
522 PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_TOP_SLEEPING
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700523 PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
524 PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
525 PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_BACKUP
526 PSS_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
527 PSS_SAME_SERVICE_INTERVAL, // ActivityManager.PROCESS_STATE_SERVICE
528 PSS_SAME_SERVICE_INTERVAL, // ActivityManager.PROCESS_STATE_RECEIVER
529 PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_HOME
530 PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
531 PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
532 PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
533 PSS_SAME_CACHED_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_EMPTY
534 };
535
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -0800536 private static final long[] sTestFirstAwakePssTimes = new long[] {
537 PSS_TEST_FIRST_TOP_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT
538 PSS_TEST_FIRST_TOP_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT_UI
539 PSS_TEST_FIRST_TOP_INTERVAL, // ActivityManager.PROCESS_STATE_TOP
Dianne Hackbornab4bb9d2015-06-05 18:08:37 -0700540 PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700541 PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
542 PSS_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_TOP_SLEEPING
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -0800543 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
544 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
545 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_BACKUP
546 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
547 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_SERVICE
548 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_RECEIVER
549 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_HOME
550 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
551 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
552 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
553 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_EMPTY
554 };
555
556 private static final long[] sTestSameAwakePssTimes = new long[] {
557 PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT
558 PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_PERSISTENT_UI
559 PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_TOP
Dianne Hackbornab4bb9d2015-06-05 18:08:37 -0700560 PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700561 PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
562 PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_TOP_SLEEPING
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -0800563 PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
564 PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
565 PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_BACKUP
566 PSS_TEST_SAME_IMPORTANT_INTERVAL, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
567 PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_SERVICE
568 PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_RECEIVER
569 PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_HOME
570 PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
571 PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
572 PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
573 PSS_TEST_SAME_BACKGROUND_INTERVAL, // ActivityManager.PROCESS_STATE_CACHED_EMPTY
574 };
575
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700576 public static boolean procStatesDifferForMem(int procState1, int procState2) {
577 return sProcStateToProcMem[procState1] != sProcStateToProcMem[procState2];
578 }
579
Dianne Hackbornae6cc8a2014-12-10 10:33:27 -0800580 public static long minTimeFromStateChange(boolean test) {
581 return test ? PSS_TEST_MIN_TIME_FROM_STATE_CHANGE : PSS_MIN_TIME_FROM_STATE_CHANGE;
582 }
583
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -0800584 public static long computeNextPssTime(int procState, boolean first, boolean test,
585 boolean sleeping, long now) {
586 final long[] table = test
Dianne Hackbornf1cca182013-08-01 10:50:28 -0700587 ? (first
Dianne Hackborn1a4b5a42014-12-08 17:43:31 -0800588 ? sTestFirstAwakePssTimes
589 : sTestSameAwakePssTimes)
Dianne Hackbornf1cca182013-08-01 10:50:28 -0700590 : (first
591 ? sFirstAwakePssTimes
592 : sSameAwakePssTimes);
593 return now + table[procState];
594 }
595
Dianne Hackborn7d608422011-08-07 16:24:18 -0700596 long getMemLevel(int adjustment) {
597 for (int i=0; i<mOomAdj.length; i++) {
598 if (adjustment <= mOomAdj[i]) {
599 return mOomMinFree[i] * 1024;
600 }
601 }
602 return mOomMinFree[mOomAdj.length-1] * 1024;
603 }
604
Todd Poynorbfdd6232013-07-10 19:15:07 -0700605 /**
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700606 * Return the maximum pss size in kb that we consider a process acceptable to
607 * restore from its cached state for running in the background when RAM is low.
608 */
Dianne Hackborncbd9a522013-09-24 23:10:14 -0700609 long getCachedRestoreThresholdKb() {
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700610 return mCachedRestoreLevel;
611 }
612
Dianne Hackborn9bef5b62013-09-20 10:40:34 -0700613 /**
Todd Poynorbfdd6232013-07-10 19:15:07 -0700614 * Set the out-of-memory badness adjustment for a process.
615 *
616 * @param pid The process identifier to set.
Colin Crossd908edd2014-06-13 14:56:04 -0700617 * @param uid The uid of the app
Todd Poynorbfdd6232013-07-10 19:15:07 -0700618 * @param amt Adjustment value -- lmkd allows -16 to +15.
619 *
620 * {@hide}
621 */
Colin Crossd908edd2014-06-13 14:56:04 -0700622 public static final void setOomAdj(int pid, int uid, int amt) {
Todd Poynorbfdd6232013-07-10 19:15:07 -0700623 if (amt == UNKNOWN_ADJ)
624 return;
625
Dianne Hackbornecf1cda2014-08-28 16:58:28 -0700626 long start = SystemClock.elapsedRealtime();
Colin Crossd908edd2014-06-13 14:56:04 -0700627 ByteBuffer buf = ByteBuffer.allocate(4 * 4);
Todd Poynorbfdd6232013-07-10 19:15:07 -0700628 buf.putInt(LMK_PROCPRIO);
629 buf.putInt(pid);
Colin Crossd908edd2014-06-13 14:56:04 -0700630 buf.putInt(uid);
Todd Poynorbfdd6232013-07-10 19:15:07 -0700631 buf.putInt(amt);
632 writeLmkd(buf);
Dianne Hackbornecf1cda2014-08-28 16:58:28 -0700633 long now = SystemClock.elapsedRealtime();
634 if ((now-start) > 250) {
635 Slog.w("ActivityManager", "SLOW OOM ADJ: " + (now-start) + "ms for pid " + pid
636 + " = " + amt);
637 }
Todd Poynorbfdd6232013-07-10 19:15:07 -0700638 }
639
640 /*
641 * {@hide}
642 */
643 public static final void remove(int pid) {
644 ByteBuffer buf = ByteBuffer.allocate(4 * 2);
645 buf.putInt(LMK_PROCREMOVE);
646 buf.putInt(pid);
647 writeLmkd(buf);
648 }
649
650 private static boolean openLmkdSocket() {
Dianne Hackborn7d608422011-08-07 16:24:18 -0700651 try {
Todd Poynorbfdd6232013-07-10 19:15:07 -0700652 sLmkdSocket = new LocalSocket(LocalSocket.SOCKET_SEQPACKET);
653 sLmkdSocket.connect(
654 new LocalSocketAddress("lmkd",
655 LocalSocketAddress.Namespace.RESERVED));
656 sLmkdOutputStream = sLmkdSocket.getOutputStream();
657 } catch (IOException ex) {
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800658 Slog.w(TAG, "lowmemorykiller daemon socket open failed");
Todd Poynorbfdd6232013-07-10 19:15:07 -0700659 sLmkdSocket = null;
660 return false;
661 }
662
663 return true;
664 }
665
666 private static void writeLmkd(ByteBuffer buf) {
667
668 for (int i = 0; i < 3; i++) {
669 if (sLmkdSocket == null) {
670 if (openLmkdSocket() == false) {
671 try {
672 Thread.sleep(1000);
673 } catch (InterruptedException ie) {
674 }
675 continue;
676 }
677 }
678
679 try {
680 sLmkdOutputStream.write(buf.array(), 0, buf.position());
681 return;
682 } catch (IOException ex) {
Wale Ogunwalee23149f2015-03-06 15:39:44 -0800683 Slog.w(TAG, "Error writing to lowmemorykiller socket");
Todd Poynorbfdd6232013-07-10 19:15:07 -0700684
Dianne Hackborn7d608422011-08-07 16:24:18 -0700685 try {
Todd Poynorbfdd6232013-07-10 19:15:07 -0700686 sLmkdSocket.close();
687 } catch (IOException ex2) {
Dianne Hackborn7d608422011-08-07 16:24:18 -0700688 }
Todd Poynorbfdd6232013-07-10 19:15:07 -0700689
690 sLmkdSocket = null;
Dianne Hackborn7d608422011-08-07 16:24:18 -0700691 }
692 }
693 }
694}