2.5.3 All kernel wake locks
按持锁时间排序,显示不同内核锁的持锁时间和次数。
batterystats
会从/proc/wakelocks和/d/wakeup_sources这两个文件中读取内核的持锁情况。有兴趣的读者可以查阅源码KernelWakelockReader.java。
All kernel wake locks:
Kernel Wake lock [timerfd] : 11m 57s 252ms (13238 times) realtime
Kernel Wake lock NETLINK : 8m 44s 333ms (32058 times) realtime
Kernel Wake lock qpnp_fg_sanity_check: 1m 49s 914ms (73 times) realtime
Kernel Wake lock alarmtimer : 1m 40s 307ms (50 times) realtime
...
一旦有内核持锁,那CPU是无法休眠的,一直以较高的频率运行导致的结果就是耗电。 上面日志中,累计持锁时间最长的是[timerfd],累计持锁13238次,累计时长11分57秒。这是一份待机12天的日志,累计最长时间的内核锁仅仅持锁了不到12分钟,说明只是一些正常的唤醒。
对于应用而言,是不能直接使用内核锁的,需要通过Android提供的Wake Lock机制,使用PowerManager接口来申请和释放锁。应用可以持有多个不同的锁,但反应到内核的锁也就三种:
- PowerManagerService.WakeLocks:控制CPU状态的锁
- PowerManagerService.Display: 控制屏幕状态的锁
- PowerManagerService.Broadcasts:控制电源状态改变的通知锁
如果在这部分日志中,发现以上三种锁持有时间很长,那说明很可能是应用使用Wake Lock不当导致的。