Watchdog机制

1.什么是SWT:

Softwere Watchdog Timeout,顾名思义就是软件超时监控狗。

Watchdog.java 位于frameworks/base/services/core/java/com/android/server/Watchdog.java

2.为什么需要SWT:

System Server 进程是Android的一个核心进程,里面为App运行提供了很多核心服务,如AMS、WMS、PKMS等等,如果这些核心的服务和重要的线程卡住,就会导致相应的功能异常。如果没有一种机制让这些服务复位的话,就会严重影响用户的体验,所以Google引入了System Server Watchdog 机制,用来监控这些核心服务和重要线程是否被卡住。

3.原理框架示意图:

4.Watchdog的初始化:

Watchdog的初始化是在SystemServer init的后期,如果SystemServer在init的过程中卡死了,那么就意味着Watchdog不会生效。

Watchdog是一个单例线程,在SystemServer启动时就会获取它并初始化和启动(init/start).

  private void startOtherServices() {...traceBeginAndSlog("InitWatchdog");final Watchdog watchdog = Watchdog.getInstance();watchdog.init(context, mActivityManagerService);traceEnd();...traceBeginAndSlog("StartWatchdog");Watchdog.getInstance().start();traceEnd();...}

Watchdog在初始化的时候会构建很多的HandlerChecker

private Watchdog() {super("watchdog");// Initialize handler checkers for each common thread we want to check.  Note// that we are not currently checking the background thread, since it can// potentially hold longer running operations with no guarantees about the timeliness// of operations there.// The shared foreground thread is the main checker.  It is where we// will also dispatch monitor checks and do other work.mMonitorChecker = new HandlerChecker(FgThread.getHandler(),"foreground thread", DEFAULT_TIMEOUT);mHandlerCheckers.add(mMonitorChecker);// Add checker for main thread.  We only do a quick check since there// can be UI running on the thread.mHandlerCheckers.add(new HandlerChecker(new Handler(Looper.getMainLooper()),"main thread", DEFAULT_TIMEOUT));// Add checker for shared UI thread.mHandlerCheckers.add(new HandlerChecker(UiThread.getHandler(),"ui thread", DEFAULT_TIMEOUT));// And also check IO thread.mHandlerCheckers.add(new HandlerChecker(IoThread.getHandler(),"i/o thread", DEFAULT_TIMEOUT));// And the display thread.mHandlerCheckers.add(new HandlerChecker(DisplayThread.getHandler(),"display thread", DEFAULT_TIMEOUT));// And the animation thread.mHandlerCheckers.add(new HandlerChecker(AnimationThread.getHandler(),"animation thread", DEFAULT_TIMEOUT));// And the surface animation thread.mHandlerCheckers.add(new HandlerChecker(SurfaceAnimationThread.getHandler(),"surface animation thread", DEFAULT_TIMEOUT));......
}

5.HandlerChecker分类:

大致可以分为两类

  • Montor Checker:用于检查Monitor对象是否发生死锁,AMP、PKMS、WMS等核心系统服务都是Monitor对象。所有需要被监控的Service都去实现了Watchdog的Monitor接口,该接口中只有一个方法 monitor()

与之对应的是addMonitor()方法,将Service放到mHandlerChecker的mMonitors列表中,该列表会不断调用Monitor.monitor()方法,这个方法的实现也比较简单,就是去获取对应的锁,如果获取到了就OK,如果线程死锁或者其它原因阻塞那么必然获取不到,monitor()方法也必然阻塞

WindowManagerService.java // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).@Overridepublic void monitor() {synchronized (mWindowMap) { }}
  • Lopper Checker,用于检查线程的消息队列是否长时间处于非空闲状态,Watchdog自身的消息队列,Ui, Io, Display这些全局的消息队列都是被检查的对象。此外,一些重要的线程的消息队列,也会加入到Looper Checker中,譬如AMS, PKMS,这些是在对应的对象初始化时加入的。

与之对应的方法是addThread(),将PowerManagerService、PackageManagerService、ActivityManagerService等几个主线程Handler保存到Watchdog.mHandlerCheckers列表中;同时还会把上面提到的mMonitorChecker也保存到Watchdog.mHandlerCheckers中;另外还会将foreground thread、ui thread、i/o thread 、display thread 、main thread的Handler也保存到Watchdog.mHandlerCheckers中来;

Watchdog会不断判断这些线程的Lopper是否空闲,如果一直非空闲,那么必然就被阻塞了。

6.Watchdog的运作:

Watchdog本身是一个线程,它的run()方法实现如下:

@Override
public void run() {boolean waitedHalf = false; //标识第一个30s超时boolean mSFHang = false; //标识surfaceflinger是否hangwhile (true) {...synchronized (this) {...// 1. 调度所有的HandlerCheckerfor (int i=0; i<mHandlerCheckers.size(); i++) {HandlerChecker hc = mHandlerCheckers.get(i);//shceduleCheckLocked()所做的事情可以想象成给所有的目标thread发放任务。hc.scheduleCheckLocked();}...// 2. 开始定期检查long start = SystemClock.uptimeMillis();while (timeout > 0) {...try {wait(timeout);} catch (InterruptedException e) {Log.wtf(TAG, e);}...timeout = CHECK_INTERVAL - (SystemClock.uptimeMillis() - start);}// 3. 检查HandlerChecker的完成状态final int waitState = evaluateCheckerCompletionLocked();if (waitState == COMPLETED) {...continue;} else if (waitState == WAITING) {...continue;} else if (waitState == WAITED_HALF) {...continue;}// 4. 存在超时的HandlerCheckerblockedCheckers = getBlockedCheckersLocked();//超了60秒,此时便出问题了,收集超时的HandlerCheckersubject = describeCheckersLocked(blockedCheckers);allowRestart = mAllowRestart;}...// 5. 保存日志,判断是否需要杀掉系统进程Slog.w(TAG, "*** GOODBYE!");Process.killProcess(Process.myPid());System.exit(10);} // end of while (true)......
}

以上代码片段主要的运行逻辑如下:

  1. Watchdog运行后,便开始无限循环,依次调用每一个HandlerChecker的scheduleCheckLocked()方法
  2. 调度完HandlerChecker之后,便开始定期检查是否超时,每一次检查的间隔时间由CHECK_INTERVAL常量设定,为30秒
  3. 每一次检查都会调用evaluateCheckerCompletionLocked()方法来评估一下HandlerChecker的完成状态:
    • COMPLETED表示已经完成
    • WAITING和WAITED_HALF表示还在等待,但未超时
    • OVERDUE表示已经超时。默认情况下,timeout是1分钟,但监测对象可以通过传参自行设定,譬如PKMS的Handler Checker的超时是10分钟
  4. 如果超时时间到了,还有HandlerChecker处于未完成的状态(OVERDUE),则通过getBlockedCheckersLocked()方法,获取阻塞的HandlerChecker,生成一些描述信息
  5. 保存日志,包括一些运行时的堆栈信息,这些日志是我们解决Watchdog问题的重要依据。如果判断需要杀掉system_server进程,则给当前进程(system_server)发送signal 9

只要Watchdog没有发现超时任务,HandlerChecker就会被不停的调度。

7.HandlerChecker的运作:

public final class HandlerChecker implements Runnable {public void scheduleCheckLocked() {// Looper Checker中是不包含monitor对象的,判断消息队列是否处于空闲if (mMonitors.size() == 0 && mHandler.getLooper().isIdling()) {mCompleted = true;return;}...// 将Monitor Checker的对象置于消息队列之前,优先运行mHandler.postAtFrontOfQueue(this);}@Overridepublic void run() {// 依次调用Monitor对象的monitor()方法for (int i = 0 ; i < size ; i++) {synchronized (Watchdog.this) {mCurrentMonitor = mMonitors.get(i);}mCurrentMonitor.monitor();}...}
}

8.小结:

  • 对于Looper Checker而言,会判断线程的消息队列是否处于空闲状态。 如果被监测的消息队列一直闲不下来,则说明可能已经阻塞等待了很长时间。
  • 对于Monitor Checker而言,会调用实现类的monitor方法,比如上文中提到的AMS.monitor()方法, 方法实现一般很简单,就是获取当前类的对象锁,如果当前对象锁已经被持有,则monitor()会一直处于wait状态,直到超时,这种情况下,很可能是线程发生了死锁。

这基本就是Watchdog的监控原理,就先梳理这么多吧,后续的SWT/ANR问题的分析流程等遇到了再说吧。

Watchdog机制原理相关推荐

  1. Redisson的看门狗watchDog机制是怎么实现的?

    文章目录 INFO 一.回顾 二.WatchDog 1.啥意思 2.原理 三.总结 INFO 作者: 编程界的小学生 日期: 2021/09/09 修订: 初版,未修订.2021/09/09 版权: ...

  2. linux的watchdog代码分析,Watchdog机制以及问题分析

    目录 1. 概览 Watchdog的中文的"看门狗",有保护的意思.最早引入Watchdog是在单片机系统中,由于单片机的工作环境容易受到外界磁场的干扰,导致程序"跑飞& ...

  3. android watchdog机制

    Android Watchdog 机制 早期手机平台上通常是在设备中增加一个硬件看门狗(WatchDog), 软件系统必须定时的向看门狗硬件中写值来表示自己没出故障(俗称"喂狗") ...

  4. 2021年大数据Kafka(九):kafka消息存储及查询机制原理

    全网最详细的大数据Kafka文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 系列历史文章 kafka消息存储及查询机制原理 一.Kafka数据存储机制 ...

  5. 【阿里云课程】注意力机制原理,应用与设计

    大家好,继续更新有三AI与阿里天池联合推出的深度学习系列课程,本次更新内容为第10课中的一节,介绍如下: 注意力机制原理与设计 本次课程是阿里天池联合有三AI推出的深度学习系列课程第10期,深度学习模 ...

  6. python类加载机制_PHP面向对象自动加载机制原理与用法分析

    本文实例讲述了PHP面向对象自动加载机制原理与用法.分享给大家供大家参考,具体如下: 在学习PHP的面向对象的时候,会知道很多"语法糖",也就是魔术方法.有一个加自动加载的魔术方法 ...

  7. Kafka设计解析(八)- Exactly Once语义与事务机制原理

    本文转发自技术世界,原文链接 http://www.jasongj.com/kafka/transaction/ 写在前面的话 本文所有Kafka原理性的描述除特殊说明外均基于Kafka 1.0.0版 ...

  8. Atitit 插件机制原理与设计微内核 c# java 的实现attilax总结

    Atitit 插件机制原理与设计微内核 c# java 的实现attilax总结 1. 微内核与插件的优点1 2. 插件的注册与使用2 2.1. Ioc容器中注册插件2 2.2. 启动器微内核启动3 ...

  9. Spark之Master主备切换机制原理

    Spark之Master主备切换机制原理

最新文章

  1. html不支持css3,ie不支持css3吗?
  2. 分布式锁之三:Redlock实现分布式锁
  3. mysql创建数据库1064_Mysql创建表过程中报1064错误
  4. 直播未来属于RTMP还是HTTP?
  5. LL-verilog 1000HZ分频为1HZ使用三个十位计数器合成
  6. Github项目汇总
  7. 身份证省市区SQL代码
  8. 小米手机刷机工具MiFlash
  9. 英文标题中的字母大写规则
  10. Hive 取非 Group by 字段数据的方法
  11. Android面试题解答(结尾有彩蛋)
  12. 一次日语翻译的Chrome插件开发经历
  13. SpringMVC框架 获取前台传过来的数组并解析
  14. 使用CoreLocation定位
  15. python时区、时差、时间差转换——datetime.timedelta类介绍
  16. 极兔、百世被罚后:每单涨价 4、5 毛
  17. .NET动态生成PDF文件(利用iTextSharp)
  18. 【多式联运】基于帝企鹅AFO 粒子群PSO 遗传GA算法求解不确定多式联运路径优化问题附matlab代码...
  19. 快速入门Unity机器学习:一:
  20. sql limit不接具体数字_SQL学习笔记【1】

热门文章

  1. 微信小程序如何获取用户头像昵称
  2. EASBOS设置UI界面窗口大小
  3. 小白对python中网页解析库pyquery的理解
  4. 机器人 陆梅东_第十一届全国青少年机器人大赛获奖名单9
  5. Kudu的架构以及优势
  6. java项目总监_写给我们项目总监的一些话
  7. 卷积神经网络的可视化(二)(可视化卷积神经网络的过滤器)
  8. GIMP:常用快捷键
  9. 1,Java语言基础-Java语言概述和必要计算机知识
  10. 原子荧光法测As含量