转自:http://blog.youkuaiyun.com/zhoumushui/article/details/51197747
当系统的内存不足时, Android系统将根据进程优先级选择杀死一些不太重要的进程。
那么进程的优先级是怎样判别的呢?对,就是这个根据进程的oom_adj值。oom_adj的值越小,进程的优先级越高。
如何查看某个应用的oom_adj数值?
首先adb shell#ps查看应用的PID
然后#cat /proc/PID/oom_adj的结果就是。
ProcessList中对oom_adj的定义,里面加了一些我个人的翻译,可能不是很精确。
frameworks/base/services/Java/com/android/server/am/ProcessList.java:
- // The minimum time we allow between crashes, for us to consider this
- // application to be bad and stop and its services and reject broadcasts.
- static final int MIN_CRASH_INTERVAL = 60*1000;
- // OOM adjustments for processes in various states:
- // Adjustment used in certain places where we don't know it yet.
- // (Generally this is something that is going to be cached, but we
- // don't know the exact value in the cached range to assign yet.)
- // ZMS:用作对一些特定的我们未知的地方进行调整。
- //(通常是一些缓存,但是我们并不知道确切的缓存划分)
- static final int UNKNOWN_ADJ = 16;
- // This is a process only hosting activities that are not visible,
- // so it can be killed without any disruption.
- // ZMS:这个是一个仅仅拥有后台不可见Activity的进程,可以被无破坏杀掉。
- static final int CACHED_APP_MAX_ADJ = 15;
- static final int CACHED_APP_MIN_ADJ = 9;
- // The B list of SERVICE_ADJ -- these are the old and decrepit
- // services that aren't as shiny and interesting as the ones in the A list.
- // ZMS:B列表Service ADJ--B列表Service是一些老旧的Service,没有A列表里的Service新。
- static final int SERVICE_B_ADJ = 8;
- // This is the process of the previous application that the user was in.
- // This process is kept above other things, because it is very common to
- // switch back to the previous app. This is important both for recent
- // task switch (toggling between the two top recent apps) as well as normal
- // UI flow such as clicking on a URI in the e-mail app to view in the browser,
- // and then pressing back to return to e-mail.
- // ZMS:这是用户前一个使用应用的进程。此进程优先级之所以排到其他缓存进程之上,
- // 是因为切回前一个应用的场景很常见……
- static final int PREVIOUS_APP_ADJ = 7;
- // This is a process holding the home application -- we want to try
- // avoiding killing it, even if it would normally be in the background,
- // because the user interacts with it so much.
- // ZMS:主界面进程--尽管它经常在后台,我们同样想避免杀掉它,毕竟用户和主界面交互很多。
- static final int HOME_APP_ADJ = 6;
- // This is a process holding an application service -- killing it will not
- // have much of an impact as far as the user is concerned.
- // ZMS:服务进程--由于用户关切,杀掉它会有不小影响。
- static final int SERVICE_ADJ = 5;
- // This is a process with a heavy-weight application. It is in the
- // background, but we want to try to avoid killing it. Value set in
- // system/rootdir/init.rc on startup.
- // ZMS:重量级应用进程。它在后台,但是我们想避免杀掉它。
- static final int HEAVY_WEIGHT_APP_ADJ = 4;
- // This is a process currently hosting a backup operation. Killing it
- // is not entirely fatal but is generally a bad idea.
- // ZMS:执行备份操作的进程。杀掉它不完全致命,但通常是个坏想法。
- static final int BACKUP_APP_ADJ = 3;
- // This is a process only hosting components that are perceptible to the
- // user, and we really want to avoid killing them, but they are not
- // immediately visible. An example is background music playback.
- // ZMS:拥有用户可感知组件的进程,所以我们尽量要避免杀掉它,尽管它不是立即可见。
- // 例如:后台音乐播放。
- static final int PERCEPTIBLE_APP_ADJ = 2;
- // This is a process only hosting activities that are visible to the
- // user, so we'd prefer they don't disappear.
- // ZMS:此进程仅仅拥有用户可见的Activity,所以我们不希望它消失。
- static final int VISIBLE_APP_ADJ = 1;
- // This is the process running the current foreground app. We'd really
- // rather not kill it!
- // ZMS:前台应用进程。最好不要杀掉它!
- static final int FOREGROUND_APP_ADJ = 0;
- // This is a system persistent process, such as telephony. Definitely
- // don't want to kill it, but doing so is not completely fatal.
- // ZMS:系统常驻进程,比如电话。绝对不想要杀死它,但是即便杀死也不是很致命。
- static final int PERSISTENT_PROC_ADJ = -12;
- // The system process runs at the default adjustment.
- // ZMS:系统进程
- static final int SYSTEM_ADJ = -16;
- // Special code for native processes that are not being managed by the system (so
- // don't have an oom adj assigned by the system).
- // ZMS:为native进程保留,他们不被系统管理。
- static final int NATIVE_ADJ = -17;
- // Memory pages are 4K.
- static final int PAGE_SIZE = 4*1024;
- // The minimum number of cached apps we want to be able to keep around,
- // without empty apps being able to push them out of memory.
- static final int MIN_CACHED_APPS = 2;
- // The maximum number of cached processes we will keep around before killing them.
- // NOTE: this constant is *only* a control to not let us go too crazy with
- // keeping around processes on devices with large amounts of RAM. For devices that
- // are tighter on RAM, the out of memory killer is responsible for killing background
- // processes as RAM is needed, and we should *never* be relying on this limit to
- // kill them. Also note that this limit only applies to cached background processes;
- // we have no limit on the number of service, visible, foreground, or other such
- // processes and the number of those processes does not count against the cached
- // process limit.
- static final int MAX_CACHED_APPS = 24;
- // We allow empty processes to stick around for at most 30 minutes.
- static final long MAX_EMPTY_TIME = 30*60*1000;
- // The maximum number of empty app processes we will let sit around.
- private static final int MAX_EMPTY_APPS = computeEmptyProcessLimit(MAX_CACHED_APPS);
- // The number of empty apps at which we don't consider it necessary to do
- // memory trimming.
- static final int TRIM_EMPTY_APPS = MAX_EMPTY_APPS/2;
- // The number of cached at which we don't consider it necessary to do
- // memory trimming.
- static final int TRIM_CACHED_APPS = ((MAX_CACHED_APPS-MAX_EMPTY_APPS)*2)/3;
- // Threshold of number of cached+empty where we consider memory critical.
- static final int TRIM_CRITICAL_THRESHOLD = 3;
- // Threshold of number of cached+empty where we consider memory critical.
- static final int TRIM_LOW_THRESHOLD = 5;
- // These are the various interesting memory levels that we will give to
- // the OOM killer. Note that the OOM killer only supports 6 slots, so we
- // can't give it a different value for every possible kind of process.
- private final int[] mOomAdj = new int[] {
- FOREGROUND_APP_ADJ, VISIBLE_APP_ADJ, PERCEPTIBLE_APP_ADJ,
- BACKUP_APP_ADJ, CACHED_APP_MIN_ADJ, CACHED_APP_MAX_ADJ
- };
- // These are the low-end OOM level limits. This is appropriate for an
- // HVGA or smaller phone with less than 512MB. Values are in KB.
- private final long[] mOomMinFreeLow = new long[] {
- 8192, 12288, 16384,
- 24576, 28672, 32768
- };
- // These are the high-end OOM level limits. This is appropriate for a
- // 1280x800 or larger screen with around 1GB RAM. Values are in KB.
- private final long[] mOomMinFreeHigh = new long[] {
- 49152, 61440, 73728,
- 86016, 98304, 122880
- };
以上代码的后面又两个数组,定义了开始回收的阈值(单位KB)。
adb shell#cat /sys/module/lowmemorykiller/parameters/minfree
查看机器当前的设定,结果乘以PAGE_SIZE 即是对应的内存阈值。
---------------------------------------------------------------------------------------
修改指定包名应用的oom_adj,避免被系统回收:
Android 4.4:frameworks/base/services/java/com/android/server/am/ActivityManagerService.java
Android 5.1:frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
- @@ -8903,6 +8903,11 @@ public final class ActivityManagerService extends ActivityManagerNative
- app.persistent = true;
- app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
- }
- + if("com.zms.test".equals(info.packageName)){
- + app.persistent = true;
- + app.maxAdj = ProcessList.SYSTEM_ADJ;
- + }
- if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
- mPersistentStartingProcesses.add(app);
- startProcessLocked(app, "added application", app.processName);