AMS 几种主动清理内存的几种方式

 

一、通过杀empty进程和cache进程来释放内存

  1. 如果空进程的个数大于mConstants.CUR_TRIM_EMPTY_PROCESSES(CUR_TRIM_EMPTY_PROCESSES 的这个依据配置值的不同而不同,具体的可以见updateMaxCachedProcesses这个函数),并且该应用的上次活跃的时间,大于半个小时,这里的活跃是指该应用有相关组件在活动,比如:在处理广播
  2. 空进程个数大于了最大限制
  3. 当cache进程达到阈值的时候,就开始杀cache进程

具体的代码位置如下:

    文件路径: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;
    }

二、通过杀isolated进程来释放内存

1.如果这是isolated进程,且这isolated进程上没有运行任何的服务,且app.isolatedEntryPoint 不为空(app.isolatedEntryPoint的进程是可以不依赖于其他进程存在的)

if (app.isolated && app.services.size() <= 0 && app.isolatedEntryPoint == null) {
       
                    app.kill("isolated not needed", true);

                } 

 

 三、通过调用onLowMemory()方法来触发BinderInternal.forceGc("mem"),会触发系统垃圾回收,或者通过onTrimMemory提示开发者当前的内存水平,应用开发者可以实现自己的onTrimMemory,依据不同的内存水平进行内存资源释放

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

 

你可能感兴趣的:(Android,Framework,Android,进程管理)