具体的代码位置如下:
文件路径:frameworks/base/services/core/java/com/android/server/am/OomAdjuster.java
方法:updateOomAdjLocked(String oomAdjReason)
代码片段:
.....
final long oldTime = now - ProcessList.MAX_EMPTY_TIME; // static final long
MAX_EMPTY_TIME = 30 * 60 * 1000;
.....
switch (app.getCurProcState()) {
case PROCESS_STATE_CACHED_ACTIVITY:
case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
mNumCachedHiddenProcs++;
numCached++;
if (app.connectionGroup != 0) {
if (lastCachedGroupUid == app.info.uid
&& lastCachedGroup == app.connectionGroup) {
// If this process is the next in the same group, we don't
// want it to count against our limit of the number of cached
// processes, so bump up the group count to account for it.
numCachedExtraGroup++;
} else {
lastCachedGroupUid = app.info.uid;
lastCachedGroup = app.connectionGroup;
}
} else {
lastCachedGroupUid = lastCachedGroup = 0;
}
if ((numCached - numCachedExtraGroup) > cachedProcessLimit) {
app.kill("cached #" + numCached, true);
}
break;
case PROCESS_STATE_CACHED_EMPTY:
if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
&& app.lastActivityTime < oldTime) {
app.kill("empty for "
+ ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
/ 1000) + "s", true);
} else {
numEmpty++;
if (numEmpty > emptyProcessLimit) {
app.kill("empty #" + numEmpty, true);
}
}
break;
default:
mNumNonCachedProcs++;
break;
}
该函数主要是用来计算empty进程和cache进程的,
private void updateMaxCachedProcesses() {
String maxCachedProcessesFlag = DeviceConfig.getProperty(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, KEY_MAX_CACHED_PROCESSES);
try {
CUR_MAX_CACHED_PROCESSES = mOverrideMaxCachedProcesses < 0
? (TextUtils.isEmpty(maxCachedProcessesFlag)
? DEFAULT_MAX_CACHED_PROCESSES : Integer.parseInt(maxCachedProcessesFlag))
: mOverrideMaxCachedProcesses;
} catch (NumberFormatException e) {
// Bad flag value from Phenotype, revert to default.
Slog.e(TAG,
"Unable to parse flag for max_cached_processes: " + maxCachedProcessesFlag, e);
CUR_MAX_CACHED_PROCESSES = DEFAULT_MAX_CACHED_PROCESSES;
}
CUR_MAX_EMPTY_PROCESSES = computeEmptyProcessLimit(CUR_MAX_CACHED_PROCESSES);
// Note the trim levels do NOT depend on the override process limit, we want
// to consider the same level the point where we do trimming regardless of any
// additional enforced limit.
// MAX_CACHED_PROCESSES 默认值是32,这个值是可以配置的,你依据你手机的物理内存的大小,
// 和你手机的实际的情况配置这个值
// rawMaxEmptyProcesses 计算完成后为16
final int rawMaxEmptyProcesses = computeEmptyProcessLimit(MAX_CACHED_PROCESSES);
// CUR_TRIM_EMPTY_PROCESSES = 8
CUR_TRIM_EMPTY_PROCESSES = rawMaxEmptyProcesses/2;
CUR_TRIM_CACHED_PROCESSES = (MAX_CACHED_PROCESSES-rawMaxEmptyProcesses)/3;
}
public static int computeEmptyProcessLimit(int totalProcessLimit) {
return totalProcessLimit/2;
}
1.如果这是isolated进程,且这isolated进程上没有运行任何的服务,且app.isolatedEntryPoint 不为空(app.isolatedEntryPoint的进程是可以不依赖于其他进程存在的)
if (app.isolated && app.services.size() <= 0 && app.isolatedEntryPoint == null) {
app.kill("isolated not needed", true);
}
1.发送GC_BACKGROUND_PROCESSES_MSG消息
2.接收消息调用performAppGcsIfAppropriateLocked
3.调用performAppGcsLocked
4.调用performAppGcLocked
5.通过 app.thread.scheduleLowMemory()回调到应用进程
6.sendMessage(H.LOW_MEMORY, null)发送LOW_MEMORY给主线程处理
7.收到消息进行处理 handleLowMemory()
8.通过callbacks.get(i).onLowMemory(),回调用的应用,对应用进行内存预警,应用可以依据不同的内存水平
进行不同程度的资源的释放
9.强制GC:BinderInternal.forceGc("mem");
/**
* Schedule the execution of all pending app GCs.
*/
final void scheduleAppGcsLocked() {
mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
if (mProcessesToGc.size() > 0) {
// Schedule a GC for the time to the next process.
ProcessRecord proc = mProcessesToGc.get(0);
1.发送GC_BACKGROUND_PROCESSES_MSG消息
Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
long now = SystemClock.uptimeMillis();
if (when < (now+mConstants.GC_TIMEOUT)) {
when = now + mConstants.GC_TIMEOUT;
}
mHandler.sendMessageAtTime(msg, when);
}
}
final class MainHandler extends Handler {
public MainHandler(Looper looper) {
super(looper, null, true);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
// 2. 接收消息调用performAppGcsIfAppropriateLocked
case GC_BACKGROUND_PROCESSES_MSG: {
synchronized (ActivityManagerService.this) {
performAppGcsIfAppropriateLocked();
}
} break;
......
}
/**
* If all looks good, perform GCs on all processes waiting for them.
*/
final void performAppGcsIfAppropriateLocked() {
if (canGcNowLocked()) {
// 3. 调用performAppGcsLocked
performAppGcsLocked();
return;
}
// Still not idle, wait some more.
scheduleAppGcsLocked();
}
/**
* Perform GCs on all processes that are waiting for it, but only
* if things are idle.
*/
final void performAppGcsLocked() {
final int N = mProcessesToGc.size();
if (N <= 0) {
return;
}
if (canGcNowLocked()) {
while (mProcessesToGc.size() > 0) {
ProcessRecord proc = mProcessesToGc.remove(0);
if (proc.getCurRawAdj() > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
<= SystemClock.uptimeMillis()) {
// To avoid spamming the system, we will GC processes one
// at a time, waiting a few seconds between each.
// 4.调用performAppGcLocked
performAppGcLocked(proc);
scheduleAppGcsLocked();
return;
} else {
// It hasn't been long enough since we last GCed this
// process... put it in the list to wait for its time.
addProcessToGcListLocked(proc);
break;
}
}
}
scheduleAppGcsLocked();
}
}
/**
* Ask a given process to GC right now.
*/
final void performAppGcLocked(ProcessRecord app) {
try {
app.lastRequestedGc = SystemClock.uptimeMillis();
if (app.thread != null) {
if (app.reportLowMemory) {
app.reportLowMemory = false;
// 5. 会调到应用进程
app.thread.scheduleLowMemory();
} else {
app.thread.processInBackground();
}
}
} catch (Exception e) {
// whatever.
}
}
/frameworks/base/core/java/android/app/ActivityThread.java
public void scheduleLowMemory() {
// 6. 发送LOW_MEMORY给主线程处理
sendMessage(H.LOW_MEMORY, null);
}
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
...
case LOW_MEMORY:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "lowMemory");
// 7. 收到消息进行处理
handleLowMemory();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
...
}
final void handleLowMemory() {
ArrayList callbacks = collectComponentCallbacks(true, null);
final int N = callbacks.size();
for (int i=0; i