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整个过程。