天天看点

JE相关问题ActivityManagerService中NullPointerException

java.lang.NullPointerException: Attempt to invoke virtual method 'void com.android.internal.app.procstats.ProcessState.reportExcessiveCpu(android.util.ArrayMap)' on a null object reference
	at com.android.server.am.ActivityManagerService.checkExcessivePowerUsageLocked(ActivityManagerService.java:22829)
	at com.android.server.am.ActivityManagerService$MainHandler.handleMessage(ActivityManagerService.java:2255)
	at android.os.Handler.dispatchMessage(Handler.java:106)
	at android.os.Looper.loop(Looper.java:164)
	at android.os.HandlerThread.run(HandlerThread.java:65)
	at com.android.server.ServiceThread.run(ServiceThread.java:46)
           

ActivityManagerService中出现了reportExcessiveCpu空指针

目前分析下来推测:

1,app进程在启动初期,就会makeActivity ProcessState,会赋值ProcessRecord里面的ProcessState成员;

2,步骤1之后,会将ProcessState加入到AMS里面的mLRUList列表;

3,遍历mLRUlist列表,使用响应ProcessRecord里面的ProcessState成员。

流程上面分析,不应该出现该空引用JE,但是从log分析下来,貌似步骤1都没有走,在步骤3中就遍历到了响应的ProcessRecord,默认步骤2还有其他路径。

会存在一种情况导致mLruList里面存在ProcessState,而其ProcessState已经是inactivie状态(processState成员为null):

1,就是在ProcessState对应的进程退出时,如果AMS要马上restart它,则会保留其ProcessRecord,但ProcessRecord里面的processState会因为makeInactive的调用而置空,对应到log里面,问题出现时,com.facebook.katana进程发生几次反复重启(50ms内触发几次),;

2,而checkExcessivePowerUsageLocked是每5mins触发一次(用于查杀后台比较占cpu的低优先进程),与1中的流程并行进行。

猜测可能由于以上流程导致,但是现在也没有想到有啥复现的好版本。

异常点处:

 该堆栈处理的过程是: 系统每5mins轮询一次过渡使用电量的进程,如果找到这种进程(电量使用超过其所对应的门限值,不同状态app的门限值是不一样的),则kill掉。

我理解,前面comments中的进程(退出过程中重启),不应该在这个过程中被kill,应过滤对这种进程的动作,避免此JE发生。

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
final void checkExcessivePowerUsageLocked() {
.....
.....
        while (i > 0) {
            i--;
            ProcessRecord app = mLruProcesses.get(i);

            //add
            if (app.baseProcessTracker == null)
            {//inactive process that restart later,we sholdn't kill it becase of the excessive power usage.
                continue;
            }
            //add

            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
.....

}
           

思路就是: Excessive Power查杀过程要忽略掉正在restart 的processstate,自测不会影响Excessive Power整个过程。