looper 暴露了乙個方法
public在looper 的loop方法有這樣一段**void
setmessagelogging(@nullable printer printer)
publiclooper輪循的時候,printer 在每個message處理的前後被呼叫 logging.println,我們可以通過設定printer,計算looper兩次獲取訊息的時間差,如果時間太長就說明handler處理時間過長,直接把堆疊資訊列印出來,就可以定位到耗時**。不過println 方法引數涉及到字串拼接,考慮效能問題,所以這種方式只推薦在debug模式下使用。static
void
loop()
msg.target.dispatchmessage(msg);
if (logging != null
) ...}}
基於此原理的開源庫代表是:blockcanary,
取名為blockcanary則是為了向leakcanary致敬,順便本庫的ui部分是從leakcanary改來的,之後可能會做一些調整。
看下blockcanary核心**:
類:loopermonitor
public原理是這樣,比較looper兩次處理訊息的時間差,比如大於3秒,就認為卡頓了。void
println(string x)
if (!mprintingstarted) else
stopdump();
//4、結束dump堆疊資訊
} }
//判斷是否卡頓的**很簡單,跟上次處理訊息時間比較,比如大於3秒,就認為卡頓了
private
boolean isblock(long
endtime)
細節的話大家可以自己去研究原始碼。
比如訊息佇列只有一條訊息,隔了很久才有訊息入隊,這種情況應該是要處理的,blockcanary是怎麼處理的呢?
這個我在blockcanary 中測試,並沒有出現此問題,所以blockcanary 是怎麼處理的?簡單分析一下原始碼:
上面這段**,注釋1和注釋2,記錄第一次處理的時間,同時呼叫startdump()方法,startdump()最終會通過handler 去執行乙個abstractsampler 類的mrunnable,**如下:
abstract可以看到,呼叫dosample之後又通過handler執行mrunnable,等於是迴圈呼叫mrunnable,直到stopdump被呼叫。class
abstractsampler }};
abstractsampler 方法有兩個類實現,stacksampler和cpusampler,分析堆疊就看stacksampler的dosample方法
protected所以,blockcanary 能做到連續呼叫幾個方法也能準確揪出耗時是哪個方法,是採用開啟迴圈去獲取堆疊資訊並儲存到linkedhashmap的方式,避免出現誤判或者漏判。核心**就先分析到這裡,其它細節大家可以自己去看原始碼。void
dosample()
synchronized
(sstackmap)
//放入linkedhashmap,時間作為key,value是堆疊資訊
sstackmap.put(system.currenttimemillis(), stringbuilder.tostring());}}
監控回放卡頓問題解析
一 問題現象 有一塊區域的監控錄影回時經常卡頓,有些點卡頓非常嚴重,有些點比較輕微 直接進入攝像頭觀察現場並無卡頓現象。二 問題診斷 ping卡頓非常嚴重的點所硬碟錄影有掉包現象,ping其它硬碟錄影機有延遲10多ms現象。三 解決方案 1.更換卡頓嚴重點所在的匯聚交換機 該卡頓點有所緩解 2.縮短...
mysql定期卡頓 MySQL卡頓和優化
1.若是是你,你怎麼處理慢查詢引發的問題,而且在之後避免這種狀況發生?sql 對於mysql的慢查詢問題,一般咱們是這麼幹的 1 開啟mysql伺服器的慢查詢記錄功能 mysql set global slow query log on mysql show variables like slow ...
關於win系統滑鼠卡頓 聲音卡頓問題
win7 64 thinkpad e420 老機 重灌系統發現聲音卡頓等問題 搜尋一下解決方案發現都沒有效果 1 改登錄檔,禁用服務法 聲音出現卡頓停頓的現象是這樣的 聽歌,開啟其他應用程式或者出現使用者安全控制提示的時候,聲音就出現卡頓現象。折騰了半天包括驅動,聲音屬性設定等都無法解決,最後度娘出...