成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Watchdog機制源碼分析

移動開發 Android
Android設計了一個軟件層面Watchdog,用于保護一些重要的系統服務,當出現故障時,通常會讓Android系統重啟,由于這種機制的存在,就經常會出現一些system_server進程被Watchdog殺掉而發生手機重啟的問題.

[[434595]]

前言

Linux引入Watchdog,在Linux內核下,當Watchdog啟動后,便設定了一個定時器,如果在超時時間內沒有對/dev/Watchdog進行寫操作,則會導致系統重啟。通過定時器實現的Watchdog屬于軟件層面;

Android設計了一個軟件層面Watchdog,用于保護一些重要的系統服務,當出現故障時,通常會讓Android系統重啟,由于這種機制的存在,就經常會出現一些system_server進程被Watchdog殺掉而發生手機重啟的問題;

今天我們就來分析下原理;

一、WatchDog啟動機制詳解

ANR機制是針對應用的,對于系統進程來說,如果長時間“無響應”,Android系統設計了WatchDog機制來管控。如果超過了“無響應”的延時,那么系統WatchDog會觸發自殺機制;

Watchdog是一個線程,繼承于Thread,在SystemServer.java里面通過getInstance獲取watchdog的對象;

1、在SystemServer.java中啟動

  1. private void startOtherServices() { 
  2.     ······ 
  3.     traceBeginAndSlog("InitWatchdog"); 
  4.     final Watchdog watchdog = Watchdog.getInstance(); 
  5.     watchdog.init(context, mActivityManagerService); 
  6.     traceEnd(); 
  7.     ······ 
  8.     traceBeginAndSlog("StartWatchdog"); 
  9.     Watchdog.getInstance().start(); 
  10.    traceEnd(); 

因為是線程,所以,只要start即可;

2、查看WatchDog的構造方法

  1. private Watchdog() { 
  2.         super("watchdog"); 
  3.         // Initialize handler checkers for each common thread we want to check.  Note 
  4.         // that we are not currently checking the background thread, since it can 
  5.         // potentially hold longer running operations with no guarantees about the timeliness 
  6.         // of operations there. 
  7.         // The shared foreground thread is the main checker.  It is where we 
  8.         // will also dispatch monitor checks and do other work
  9.         mMonitorChecker = new HandlerChecker(FgThread.getHandler(), 
  10.                 "foreground thread", DEFAULT_TIMEOUT); 
  11.         mHandlerCheckers.add(mMonitorChecker); 
  12.         // Add checker for main thread.  We only do a quick check since there 
  13.         // can be UI running on the thread. 
  14.         mHandlerCheckers.add(new HandlerChecker(new Handler(Looper.getMainLooper()), 
  15.                 "main thread", DEFAULT_TIMEOUT)); 
  16.         // Add checker for shared UI thread. 
  17.         mHandlerCheckers.add(new HandlerChecker(UiThread.getHandler(), 
  18.                 "ui thread", DEFAULT_TIMEOUT)); 
  19.         // And also check IO thread. 
  20.         mHandlerCheckers.add(new HandlerChecker(IoThread.getHandler(), 
  21.                 "i/o thread", DEFAULT_TIMEOUT)); 
  22.         // And the display thread. 
  23.         mHandlerCheckers.add(new HandlerChecker(DisplayThread.getHandler(), 
  24.                 "display thread", DEFAULT_TIMEOUT)); 
  25.         // Initialize monitor for Binder threads. 
  26.         addMonitor(new BinderThreadMonitor()); 
  27.         mOpenFdMonitor = OpenFdMonitor.create(); 
  28.         // See the notes on DEFAULT_TIMEOUT. 
  29.         assert DB || 
  30.                 DEFAULT_TIMEOUT > ZygoteConnectionConstants.WRAPPED_PID_TIMEOUT_MILLIS; 
  31.         // mtk enhance 
  32.         exceptionHWT = new ExceptionLog(); 
  33.     } 

重點關注兩個對象:mMonitorChecker和mHandlerCheckers

mHandlerCheckers列表元素的來源:

構造對象的導入:UiThread、IoThread、DisplatyThread、FgThread加入

外部導入:Watchdog.getInstance().addThread(handler);

mMonitorChecker列表元素的來源:

外部導入:Watchdog.getInstance().addMonitor(monitor);

特別說明:addMonitor(new BinderThreadMonitor());

3、查看WatchDog的run方法

  1. public void run() { 
  2.         boolean waitedHalf = false
  3.         boolean mSFHang = false
  4.         while (true) { 
  5.             ······ 
  6.             synchronized (this) { 
  7.                 ······ 
  8.                 for (int i=0; i<mHandlerCheckers.size(); i++) { 
  9.                     HandlerChecker hc = mHandlerCheckers.get(i); 
  10.                     hc.scheduleCheckLocked(); 
  11.                 } 
  12.                 ······ 
  13.             } 
  14.             ······ 

對mHandlerCheckers列表元素進行檢測;

4、查看HandlerChecker的scheduleCheckLocked

  1. public void scheduleCheckLocked() { 
  2.         if (mMonitors.size() == 0 && mHandler.getLooper().getQueue().isPolling()) { 
  3.                 // If the target looper has recently been polling, then 
  4.                 // there is no reason to enqueue our checker on it since that 
  5.                 // is as good as it not being deadlocked.  This avoid having 
  6.                 // to do a context switch to check the thread.  Note that we 
  7.                 // only do this if mCheckReboot is false and we have no 
  8.                 // monitors, since those would need to be executed at this point. 
  9.                 mCompleted = true
  10.                 return
  11.         } 
  12.         if (!mCompleted) { 
  13.                 // we already have a check in flight, so no need 
  14.                 return
  15.         } 
  16.         mCompleted = false
  17.         mCurrentMonitor = null
  18.         mStartTime = SystemClock.uptimeMillis(); 
  19.         mHandler.postAtFrontOfQueue(this); 

mMonitors.size() == 0的情況:主要為了檢查mHandlerCheckers中的元素是否超時,運用的手段:mHandler.getLooper().getQueue().isPolling();

mMonitorChecker對象的列表元素一定是大于0,此時,關注點在mHandler.postAtFrontOfQueue(this);

  1. public void run() { 
  2.        final int size = mMonitors.size(); 
  3.        for (int i = 0 ; i < size ; i++) { 
  4.             synchronized (Watchdog.this) { 
  5.                 mCurrentMonitor = mMonitors.get(i); 
  6.             } 
  7.             mCurrentMonitor.monitor(); 
  8.        } 
  9.        synchronized (Watchdog.this) { 
  10.             mCompleted = true
  11.             mCurrentMonitor = null
  12.        } 

監聽monitor方法,這里是對mMonitors進行monitor,而能夠滿足條件的只有:mMonitorChecker,例如:各種服務通過addMonitor加入列表;

  1. ActivityManagerService.java 
  2.     Watchdog.getInstance().addMonitor(this);  
  3. InputManagerService.java 
  4.     Watchdog.getInstance().addMonitor(this);  
  5. PowerManagerService.java 
  6.     Watchdog.getInstance().addMonitor(this);  
  7. ActivityManagerService.java 
  8.     Watchdog.getInstance().addMonitor(this);  
  9. WindowManagerService.java 
  10.     Watchdog.getInstance().addMonitor(this); 

而被執行的monitor方法很簡單,例如ActivityManagerService:

  1. public void monitor() { 
  2.      synchronized (this) { } 

這里僅僅是檢查系統服務是否被鎖住;

Watchdog的內部類;

  1. private static final class BinderThreadMonitor implements Watchdog.Monitor { 
  2.         @Override 
  3.         public void monitor() { 
  4.             Binder.blockUntilThreadAvailable(); 
  5.         } 
  6. android.os.Binder.java 
  7. public static final native void blockUntilThreadAvailable(); 
  8. android_util_Binder.cpp 
  9. static void android_os_Binder_blockUntilThreadAvailable(JNIEnv* env, jobject clazz) 
  10.     return IPCThreadState::self()->blockUntilThreadAvailable(); 
  11. IPCThreadState.cpp 
  12. void IPCThreadState::blockUntilThreadAvailable() 
  13.     pthread_mutex_lock(&mProcess->mThreadCountLock); 
  14.     while (mProcess->mExecutingThreadsCount >= mProcess->mMaxThreads) { 
  15.         ALOGW("Waiting for thread to be free. mExecutingThreadsCount=%lu mMaxThreads=%lu\n"
  16.                 static_cast<unsigned long>(mProcess->mExecutingThreadsCount), 
  17.                 static_cast<unsigned long>(mProcess->mMaxThreads)); 
  18.         pthread_cond_wait(&mProcess->mThreadCountDecrement, &mProcess->mThreadCountLock); 
  19.     } 
  20.     pthread_mutex_unlock(&mProcess->mThreadCountLock); 

這里僅僅是檢查進程中包含的可執行線程的數量不能超過mMaxThreads,如果超過了最大值(31個),就需要等待;

  1. ProcessState.cpp 
  2. #define DEFAULT_MAX_BINDER_THREADS 15 
  3. 但是systemserver.java進行了設置 
  4. // maximum number of binder threads used for system_server 
  5. // will be higher than the system default 
  6. private static final int sMaxBinderThreads = 31; 
  7. private void run() { 
  8.     ······ 
  9.     BinderInternal.setMaxThreads(sMaxBinderThreads); 
  10.     ······ 

5、發生超時后退出

  1. public void run() { 
  2.     ······ 
  3.     Process.killProcess(Process.myPid()); 
  4.     System.exit(10); 
  5.     ······ 

kill自己所在進程(system_server),并退出;

二、原理解釋

1、系統中所有需要監控的服務都調用Watchdog的addMonitor添加Monitor Checker到mMonitors這個List中或者addThread方法添加Looper Checker到mHandlerCheckers這個List中;

2、當Watchdog線程啟動后,便開始無限循環,它的run方法就開始執行;

  • 第一步調用HandlerChecker#scheduleCheckLocked處理所有的mHandlerCheckers
  • 第二步定期檢查是否超時,每一次檢查的間隔時間由CHECK_INTERVAL常量設定,為30秒,每一次檢查都會調用evaluateCheckerCompletionLocked()方法來評估一下HandlerChecker的完成狀態:
  • COMPLETED表示已經完成;
  • WAITING和WAITED_HALF表示還在等待,但未超時,WAITED_HALF時候會dump一次trace.
  • OVERDUE表示已經超時。默認情況下,timeout是1分鐘;

3、如果超時時間到了,還有HandlerChecker處于未完成的狀態(OVERDUE),則通過getBlockedCheckersLocked()方法,獲取阻塞的HandlerChecker,生成一些描述信息,保存日志,包括一些運行時的堆棧信息。

4、最后殺死SystemServer進程;

總結

Watchdog是一個線程,用來監聽系統各項服務是否正常運行,沒有發生死鎖;

HandlerChecker用來檢查Handler以及monitor;

monitor通過鎖來判斷是否死鎖;

超時30秒會輸出log,超時60秒會重啟;

Watchdog會殺掉自己的進程,也就是此時system_server進程id會變化;

本文轉載自微信公眾號「Android開發編程」

 

責任編輯:姜華 來源: Android開發編程
相關推薦

2012-05-31 02:54:07

HadoopJava

2024-08-30 10:40:12

2023-08-28 07:49:24

Redisson鎖機制源碼

2021-12-06 14:52:08

動畫Android補間動畫

2020-05-26 18:50:46

JVMAttachJava

2021-03-16 21:45:59

Python Resize機制

2023-06-15 14:09:00

解析器Servlet容器

2011-03-15 11:33:18

iptables

2014-08-26 11:11:57

AsyncHttpCl源碼分析

2011-06-23 13:10:39

Python 對象機制

2024-09-06 09:37:45

WebApp類加載器Web 應用

2011-08-24 16:59:59

LuaModule

2014-07-18 11:11:16

SEAndroid

2023-10-31 16:00:51

類加載機制Java

2011-05-26 10:05:48

MongoDB

2021-08-12 16:28:10

AndroidHandleLooper

2011-05-26 16:18:51

Mongodb

2010-04-16 11:17:33

hints調整

2017-08-16 16:20:01

Linux內核態搶占用戶態搶占

2022-11-02 15:56:45

littlefscommit機制
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产欧美日韩在线 | 永久网站 | 日韩视频区 | 天天操天天拍 | 欧美一卡二卡在线观看 | 看a网站| 国产精品久久久久久吹潮 | 99日韩| 好姑娘影视在线观看高清 | 精品福利在线 | 精品一区二区三区在线视频 | 亚洲精品在线观 | a在线观看免费 | 午夜精品久久久久久久星辰影院 | 黄色免费网址大全 | www.国产一区 | 久久91精品国产一区二区 | 九九热在线观看视频 | 一区二区三区久久 | 国产精品国产三级国产aⅴ中文 | 国产精品欧美一区二区三区不卡 | 黄色网址av | 成人福利电影 | 欧美大片在线观看 | 免费性视频 | 在线一区 | 国产精品一二三区 | 国产探花在线精品一区二区 | 欧洲一区二区三区 | 日日操视频 | 91精品国产综合久久婷婷香蕉 | 精品国产一区二区在线 | 一区二区三区四区国产 | 国产精品久久久久久久久久久久久久 | 日韩一区二区在线视频 | 国产精品美女久久久久久久网站 | 美女黄视频网站 | 久久久久久91 | 日韩精品成人 | 99热在线观看精品 | 免费在线观看一区二区三区 |