Android Low on memory问题

话不多说,先贴上测试提出来的bug
在这里插入图片描述
尽管我极力说,这个不算bug,但是人家就是不相信,只好给测试萌妹写一个分析过程了。

这句log在logcat 中的输出如下:

26780 19882 I ActivityManager: Low on memory:
26780 19882 I ActivityManager:   ntv   ??  172100: idps_sc (pid 2257) native
26780 19882 I ActivityManager:   ntv   ??   34873: surfaceflinger (pid 1643) nativ
...

说明是 ActivityManagerService打印出来的,那么我们看一下代码打印的地方

void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
		...省略
        tag.append("Low on memory -- ");
        appendMemBucket(tag, totalPss, "total", false);
        appendMemBucket(stack, totalPss, "total", true);
		...省略
    }

调用这个方法地方在

case REPORT_MEM_USAGE_MSG: {
    final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
    Thread thread = new Thread() {
        @Override public void run() {
            reportMemUsage(memInfos);
        }
    };
    thread.start();
    break;
}

REPORT_MEM_USAGE_MSG这个这个消息是在

    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
    	...省略
        if (!haveBg) {
        	// 1.只有当ro.debuggable 为1的时候 doReport才为true ,大概率是在userdebug版本
            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
              	...省略
            }
            if (doReport) {
	            // 2. 当doReport为true的时候才会发出REPORT_MEM_USAGE_MSG 这条消息
                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
                mHandler.sendMessage(msg);
            }
            scheduleAppGcsLocked();
        }
    }

而doLowMemReportIfNeededLocked这个方法的调用:
1、在killAllBackgroundProcesses里面
2、在appDiedLocked里面,在appDiedLocked中会先判断app.killedByAm,如果是am kill的,则不会report信息,但是日志中的是lmk杀死的,则会report这条信息

如果要看appDiedLocked这个方法,首先要知道在ActivityThread.main()中,从这里开始进程创建之后会从这个方法开始绑定AMS,在AMS中通过调用AMS.attachApplicationLocked()这个方法开始绑定,在这个方法中会有对ApplicationThreadProxy绑定通知,见代码:

private final boolean attachApplicationLocked(IApplicationThread thread,
        int pid) {
    //绑定死亡通知,此处thread真实数据类型为ApplicationThreadProxy
    AppDeathRecipient adr = new AppDeathRecipient(app, pid, thread);
    thread.asBinder().linkToDeath(adr, 0);
    app.deathRecipient = adr;
}

在这个过程中,当我们binder server挂掉后,会回调AppDeathRecipient.binderDied()方法通知client端。
那到这里我们的server端是指应用进程的ApplicationThread,其中ApplicationThread是在ActivityThread中创建的此时属于新建的进程(比如新建app的进程)。client就是ApplicationThreadProxy对象,这个对象是在AMS中,AMS是在system_server中。所以当我们binder server端死亡的时候(app进程死亡)我们system_server进程就会收到通知,然后做一些处理。在这盗用一波别人花的流程图:
在这里插入图片描述
然后我们看一下appDiedLocked这个方法

@GuardedBy("this")
    final void appDiedLocked(ProcessRecord app) {
       appDiedLocked(app, app.pid, app.thread, false);
    }

    @GuardedBy("this")
    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
            boolean fromBinderDied) {
        // First check if this ProcessRecord is actually active for the pid.
        synchronized (mPidsSelfLocked) {
            ProcessRecord curProc = mPidsSelfLocked.get(pid);
            if (curProc != app) {
                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": "
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值