Watchdog简介
Watchdog是Android系统提供的以后总检查系统异常的机制,正如其名,“看门狗”,它看的是Android框架层的几个核心服务。Watchdog一旦发现的AMS、WMS和PMS等核心服务的主线程阻塞,就清除systemserver进程,我们知道,一单SystemServer进程停止,Zygote进程就会自杀,系统就会重启。
Watchdog继承Thread,它是一个线程类,它的监控任务运行在独立的线程中,其中有两个非常重要的ArrayList变量,分别是mMonitors和mHandlerCheckers。变量mMonitors存放的是对象Monitor的子类,如AMS、PMS等。对于这类的监控主要是判断它们是否死锁。而对于变量mHandlerCheckers是ArrayList集合,里面存放的是HandlerChecker的对象,Watchdog主要是监控它里面重要的线程的handler是否阻塞,即监控重要线程的消息队列是否阻塞。mMonitors是一个HandlerChecker类型的对象。实际上,HandlerChecker类是Watchdog的核心,它负责对各个监控对象进行监控。具体的对应关系如下图所示:
Watchdog的启动
Watchdog在SystemServer系统服务进程中被初始化和启动,接下来看看SystemServer怎么把它初始化和启动起来:
当SystemServer进程启动之后,就会进入它的main()方法,而它的main()方法有调用了startOtherService()方法,这个方法就把Watchdog启动起来了。startOtherService()方法首先通过Watchdog的getInstance()方法获得Watchdog对象,使用的是单例模式。接着调用init()方法来做进一步操作,最后调用Watchdog的start()方法启动线程进行监控。
|
|
接下来看看Watchdog的init()方法:
init()方法的实现比较简单,主要是给mActivity对象赋值,mActivity是一个全局的AMS对象,init()方法中会注册重启广播接收器RebotRequestReceiver,用来负责接收系统内部发出的系统重启请求。
Watchdog的监听
Watchdog继承Thread,所以调用start()方法之后,就会进入Watchdog的run()方法,它来做监控工作。
Watchdog主要提供了addMonitor()方法来添加监控服务对象,而在添加这些服务对象到Watchdog监控之前,这些服务必须要实现Watchdog.Monitor接口。比如AMS就首先实现了Watchdog.Monitor接口,然后在它的构造方法里把自己添加到Watchdog中,让Watchdog检测自己是否死锁,代码如下:
通过addMonitor()方法和addThread()方法,分别把AMS和mHandler添加到Watchdog中。mHandler是一个AMS中的Handler对象,意思是Watchdog不仅要监控AMS是否死锁,还要监控mHandler分发消息的时候是否阻塞。接下来看看Watchdog的addMonitor()方法:
AMS实现了Watchdog.Monitor接口,所以这个monitor就是AMS对象。mMontorChecker是一个HandlerChecker对象,HandlerChecker类实现了java的Runnable类:
mMontors是一个Monitor类型的ArrayList,系统启动完成之后,系统服务都会添加到这个mMonitors中。AMS中还调用了Watchdog的addThread()方法,下面了解一下:
mHandlerCheckers是一个HandlerChecker的ArrayList:
通过mHandlerCheckers的add()方法把Handler添加进去,从而监控那些重要的线程里的Handler是否阻塞。
当调用Watchdog.getInstance().start()时,则进入线程“watchdog”的run()方法, 该方法分成两部分:
- 前半段用于监测是否触发超时
- 后半段当触发超时时输出各种信息,最后杀死SystemServer进程
接下来进入Watchdog的run()方法:
该方法主要功能:
- 执行所有的Checker的监控方法scheduleCheckLocked()
- 当mMonitor个数为0(除了android.fg线程之外都为0)且处于poll状态,则设置mCompleted = true;
- 当上次check还没有完成, 则直接返回.
- 等待30s后, 再调用evaluateCheckerCompletionLocked来评估Checker状态;
- 根据waitState状态来执行不同的操作:
- 当COMPLETED或WAITING,则相安无事;
- 当WAITED_HALF(超过30s)且为首次, 则输出system_server和3个Native进程的traces;
- 当OVERDUE, 则输出更多信息.
接下来看看scheduleCheckLocked()方法:
该方法主要功能: 向Watchdog的监控线程的Looper池的最头部执行该HandlerChecker.run()方法, 在该方法中调用monitor(),执行完成后会设置mCompleted = true. 那么当handler消息池当前的消息, 导致迟迟没有机会执行monitor()方法, 则会触发watchdog
其中postAtFrontOfQueue(this),该方法输入参数为Runnable对象,根据消息机制, 最终会回调HandlerChecker中的run方法,该方法会循环遍历所有的Monitor接口,具体的服务实现该接口的monitor()方法。而monitor()方法只是简单获取锁,如AMS的monitor方法:
因此,AMS判断是否死锁就是去看能不能拿到自己的锁
run()方法后面的实现则是当触发超时时输出各种信息,最后杀死SystemServer进程,此处就不继续贴出源码了。。。。
Watchdog总结
Watchdog是一个运行在system_server进程的名为”watchdog”的线程::
- Watchdog运作过程,当阻塞时间超过1分钟则触发一次watchdog,会杀死system_server,触发上层重启;
- mHandlerCheckers:记录所有的HandlerChecker对象的列表,包括foreground, main, ui, i/o, display线程的handler;
- mHandlerChecker.mMonitors:记录所有Watchdog目前正在监控Monitor,所有的这些monitors都运行在foreground线程。
- 有两种方式加入Watchdog的监控:
- addThread():用于监测Handler对象,默认超时时长为60s.这种超时往往是所对应的handler线程消息处理得慢;
- addMonitor(): 用于监控实现了Watchdog.Monitor接口的服务.这种超时可能是”android.fg”线程消息处理得慢,也可能是monitor迟迟拿不到锁;