日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

Android system server之WatchDog看门狗分析

發布時間:2025/4/5 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android system server之WatchDog看门狗分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
android -- WatchDog看門狗分析


在由單片機構成的微型計算機系統中,由于單片機的工作常常會受到來自外界電磁場的干擾,造成程序的跑飛,而陷入死循環,程序的正常運行被打斷,由單片機控制的系統無法繼續工作,會造成整個系統的陷入停滯狀態,發生不可預料的后果,所以出于對單片機運行狀態進行實時監測的考慮,便產生了一種專門用于監測單片機程序運行狀態的芯片,俗稱"看門狗"。


在Android系統中也需要看好幾個重要的Service門,用于發現出了問題的Service殺掉SystemServer進程,所以有必要了解并分析其系統問題。

那么被監控的有哪些Service呢?

ActivityManagerService.java :frameworks\base\services\java\com\android\server\am
PowerManagerService.java ? ?:frameworks\base\services\java\com\android\server
WindowManagerService.java ? :frameworks\base\services\java\com\android\server



下面就依次分析一下其整個處理流程:

1、初始化
run @ SysemServer.java
?? ? ?Slog.i(TAG, "Init Watchdog");
?? ? ?Watchdog.getInstance().init(context, battery, power, alarm,
?? ? ? ? ? ? ?ActivityManagerService.self());


這里使用單例模式創建:
?? ?public static Watchdog getInstance() {
?? ? ? ?if (sWatchdog == null) {
?? ? ? ? ? ?sWatchdog = new Watchdog();
?? ? ? ?}
?? ? ? ?return sWatchdog;
?? ?}

?? ?public void init(Context context, BatteryService battery,
?? ? ? ? ? ?PowerManagerService power, AlarmManagerService alarm,
?? ? ? ? ? ?ActivityManagerService activity) {
?? ? ? ?// 上下文環境變量
?? ? ? ?mResolver = context.getContentResolver();
?? ? ? ?mBattery = battery;
?? ? ? ?mPower = power;
?? ? ? ?mAlarm = alarm;
?? ? ? ?mActivity = activity;


// 登記 RebootReceiver() 接收,用于reboot廣播接收使用 ?? ? ? ?context.registerReceiver(new RebootReceiver(),

?? ? ? ? ? ? ? ?new IntentFilter(REBOOT_ACTION));


... // 系統啟動時間 ?? ? ? ?mBootTime = System.currentTimeMillis();
?? ?}


ok,調用init函數啟動完畢

2、運行中
run @ SysemServer.java
調用 Watchdog.getInstance().start(); 啟動看門狗

首先看下 Watchdog 類定義:
/** This class calls its monitor every minute. Killing this process if they don't return **/
public class Watchdog extends Thread {
}


從線程類中繼承,即會在一個單獨線程中運行,調用thrrad.start()即調用 Watchdog.java 中的 run() 函數

?? ?public void run() {
?? ? ? ?boolean waitedHalf = false;


?? ? ? ?while (true) {
?? ? ? ? ? ?mCompleted = false;
?? ? ? ? ? ?
?? ? ? ? ? ?// 1、給mHandler發送 MONITOR 消息,用于請求檢查 Service是否工作正常
?? ? ? ? ? ?mHandler.sendEmptyMessage(MONITOR);


?? ? ? ? ? ?synchronized (this) {
// 2、進行 wait 等待 timeout 時間確認是否退出循環 ? ? ? ? ? ? ?? ? ? ? ? ? ? ?long timeout = TIME_TO_WAIT; ? ? ? ? ? ? ? ?
?? ? ? ? ? ? ? ?// NOTE: We use uptimeMillis() here because we do not want to increment the time we
?? ? ? ? ? ? ? ?// wait while asleep. If the device is asleep then the thing that we are waiting
?? ? ? ? ? ? ? ?// to timeout on is asleep as well and won't have a chance to run, causing a false
?? ? ? ? ? ? ? ?// positive on when to kill things.
?? ? ? ? ? ? ? ?long start = SystemClock.uptimeMillis();
?? ? ? ? ? ? ? ?while (timeout > 0 && !mForceKillSystem) {
?? ? ? ? ? ? ? ? ? ?try {
?? ? ? ? ? ? ? ? ? ? ? ?wait(timeout); ?// notifyAll() is called when mForceKillSystem is set
?? ? ? ? ? ? ? ? ? ?} catch (InterruptedException e) {
?? ? ? ? ? ? ? ? ? ? ? ?Log.wtf(TAG, e);
?? ? ? ? ? ? ? ? ? ?}
?? ? ? ? ? ? ? ? ? ?timeout = TIME_TO_WAIT - (SystemClock.uptimeMillis() - start);
?? ? ? ? ? ? ? ?}

// 3、如果 mCompleted 為真表示service一切正常,后面會再講到 ?? ? ? ? ? ? ? ?if (mCompleted && !mForceKillSystem) {
?? ? ? ? ? ? ? ? ? ?// The monitors have returned.
?? ? ? ? ? ? ? ? ? ?waitedHalf = false;
?? ? ? ? ? ? ? ? ? ?continue;
?? ? ? ? ? ? ? ?}


// 4、表明檢測到了有 deadlock-detection 條件發生,利用 dumpStackTraces 打印堆棧依信息 ?? ? ? ? ? ? ? ?if (!waitedHalf) {
?? ? ? ? ? ? ? ? ? ?// We've waited half the deadlock-detection interval. ?Pull a stack
?? ? ? ? ? ? ? ? ? ?// trace and wait another half.
?? ? ? ? ? ? ? ? ? ?ArrayList<Integer> pids = new ArrayList<Integer>();
?? ? ? ? ? ? ? ? ? ?pids.add(Process.myPid());
?? ? ? ? ? ? ? ? ? ?ActivityManagerService.dumpStackTraces(true, pids, null, null);
?? ? ? ? ? ? ? ? ? ?waitedHalf = true;
?? ? ? ? ? ? ? ? ? ?continue; // 不過這里會再次檢測一次
?? ? ? ? ? ? ? ?}
}

SystemClock.sleep(2000);
?? ? ? ? ? ?
?? ? ? ? ? ?// 5、打印內核棧調用關系
?? ? ? ? ? ?// Pull our own kernel thread stacks as well if we're configured for that
?? ? ? ? ? ?if (RECORD_KERNEL_THREADS) {
?? ? ? ? ? ? ? ?dumpKernelStackTraces();
?? ? ? ? ? ?}


// 6、ok,系統出問題了,檢測到某個 Service 出現死鎖情況,殺死SystemServer進程 ?? ? ? ? ? ?// Only kill the process if the debugger is not attached.
?? ? ? ? ? ?if (!Debug.isDebuggerConnected()) {
?? ? ? ? ? ? ? ?Slog.w(TAG, "*** WATCHDOG KILLING SYSTEM PROCESS: " + name);
?? ? ? ? ? ? ? ?Process.killProcess(Process.myPid());
?? ? ? ? ? ? ? ?System.exit(10);
?? ? ? ? ? ?} else {
?? ? ? ? ? ? ? ?Slog.w(TAG, "Debugger connected: Watchdog is *not* killing the system process");
?? ? ? ? ? ?}


?? ? ? ? ? ?waitedHalf = false;
?? ? ? ?}
?? ?}


主要工作邏輯:監控線程每隔一段時間發送一條 MONITOR 線另外一個線程,另個一個線程會檢查各個 Service 是否正常運行,看門狗就不停的檢查并等待結果,失敗則殺死SystemServer.


3、Service 檢查線程

?? ?/**
?? ? * Used for scheduling monitor callbacks and checking memory usage.
?? ? */
?? ?final class HeartbeatHandler extends Handler {
@Override
?? ?public void handleMessage(Message msg) { ?// Looper 消息處理函數
?? ? ? ? ? ?switch (msg.what) {
?? ? ? ? ? ?
?? ? ? ? ? ? ? ?case MONITOR: {
?? ? ? ? ? ? ? ?

?? ? ? ? ? ? ? ?// 依次檢測各個服務,即調用 monitor() 函數

?? ? ? ? ? ? ? ? ? ?final int size = mMonitors.size();

?? ? ? ? ? ? ? ? ? ?for (int i = 0 ; i < size ; i++) {
?? ? ? ? ? ? ? ? ? ? ? ?mCurrentMonitor = mMonitors.get(i);
?? ? ? ? ? ? ? ? ? ? ? ?mCurrentMonitor.monitor();
?? ? ? ? ? ? ? ? ? ?}


// 檢測成功則設置 mCompleted 變量為 true ?? ? ? ? ? ? ? ? ? ?synchronized (Watchdog.this) {
?? ? ? ? ? ? ? ? ? ? ? ?mCompleted = true;
?? ? ? ? ? ? ? ? ? ? ? ?mCurrentMonitor = null;
?? ? ? ? ? ? ? ? ? ?}

下面我們來看一下各個Service如何確定自已運行ok呢?以 ActivityManagerService 為例:

首先加入檢查隊列:
private ActivityManagerService() {
?? ? ? ?// Add ourself to the Watchdog monitors.
?? ? ? ?Watchdog.getInstance().addMonitor(this);
}


然后實現 monitor() 函數:
?? ?/** In this method we try to acquire our lock to make sure that we have not deadlocked */
?? ?public void monitor() {
?? ? ? ?synchronized (this) { }
?? ?}

明白了吧,其實就是檢查這個 Service 是否發生了死鎖,對于此情況就只能kill SystemServer系統了。對于死鎖的產生原因非常多,但有個情況需要注意:java層死鎖可能發生在調用native函數,而native函數可能與硬件交互導致時間過長而沒有返回,從而導致長時間占用導致問題。


4、內存使用檢測
消息發送 final class GlobalPssCollected implements Runnable { ?? ? ? ?public void run() {
?? ? ? ? ? ?mHandler.sendEmptyMessage(GLOBAL_PSS);
?? ? ? ?}
?? ?}
?? ?
?? ?檢測內存處理函數:
?? ?final class HeartbeatHandler extends Handler {
?? ? ? ?@Override
?? ? ? ?public void handleMessage(Message msg) {
?? ? ? ? ? ?switch (msg.what) {
?? ? ? ? ? ? ? ?case GLOBAL_PSS: {
?? ? ? ? ? ? ? ? ? ?if (mHaveGlobalPss) {
?? ? ? ? ? ? ? ? ? ? ? ?// During the last pass we collected pss information, so
?? ? ? ? ? ? ? ? ? ? ? ?// now it is time to report it.
?? ? ? ? ? ? ? ? ? ? ? ?mHaveGlobalPss = false;
?? ? ? ? ? ? ? ? ? ? ? ?if (localLOGV) Slog.v(TAG, "Received global pss, logging.");
?? ? ? ? ? ? ? ? ? ? ? ?logGlobalMemory(); ?? ? ? ? ? ? ? ? ? ?}
?? ? ? ? ? ? ? ?} break;
?? ? ? ? ? ? ? ?
?? ? ? ?
?? ? ? ?其主要功能如下,統計pSS狀況及讀取相關linux內核中內存信息:
?? ? ? ?void logGlobalMemory() { ? ? ? ?
?? ? ? ?mActivity.collectPss(stats);
?? ? ? ?
?? ? ? ?Process.readProcLines("/proc/meminfo", mMemInfoFields, mMemInfoSizes);
?? ? ? ?
?? ? ? ?Process.readProcLines("/proc/vmstat", mVMStatFields, mVMStatSizes); ? ? ? ?

?? ? ? ?}

原文:http://blog.csdn.net/andyhuabing/article/details/7395391

總結

以上是生活随笔為你收集整理的Android system server之WatchDog看门狗分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。