最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

突然彈出王者榮耀停止運(yùn)行,GC超時導(dǎo)致的后臺應(yīng)用崩潰問題分析

2022-07-05 18:46 作者:初壹十五阿  | 我要投稿


寫在前面

這個問題之所以會拿出來仔細(xì)分析,一方面是因?yàn)檫@個問題不是簡單的應(yīng)用崩潰而是框架層的報錯,另一方面是因?yàn)橄Mㄟ^這個問題梳理下后臺GC的超時檢測機(jī)制怎樣的,這樣我們后面在應(yīng)用層如果重寫finalize方法回收時會考慮的更加全面點(diǎn)。


問題背景

復(fù)現(xiàn)概率: 偶現(xiàn)
問題版本:?Android R
問題現(xiàn)象: 處于微信界面,突然彈出王者榮耀停止運(yùn)行

初步分析

拿到問題日志后,先看下報錯的堆棧

單單從這段堆??吹脑挘?code>BulkCursorToCursorAdaptor執(zhí)行finalize超過了10s,導(dǎo)致FinalizerWatchdogDaemon報錯,FinalizerWatchdogDaemon字面上看像是監(jiān)測回收超時的守護(hù)線程。
看下FinalizerWatchdogDaemon代碼中的作用解釋

簡單解釋下就是:如果對象的finalize出現(xiàn)阻塞超時了會導(dǎo)致進(jìn)程退出

這個問題中對應(yīng)的是數(shù)據(jù)庫的關(guān)閉,當(dāng)然也可以發(fā)生在其它場景下,只要重寫了成員函數(shù)finalize的對象都有可能會遇到這個問題,所以如果再遇到GC超時的報錯,報錯堆棧AndroidRuntime:at java.lang.Daemons$上面的內(nèi)容可能會不一樣。
那么對于重寫了成員函數(shù)finalize的對象,當(dāng)它們被GC決定要被回收時,會立刻回收嗎?
其實(shí)不會馬上被回收,而是被放入到一個隊列中,等待FinalizerDaemon守護(hù)線程去調(diào)用它們的成員函數(shù)finalize后再被回收。

超時閾值

注釋中對于該值的說明是它很快將被移除,實(shí)際這個值在代碼中并沒有起到真正的作用了,更新它的值是為了方便在外邊讀取到。
真正的超時閾值是通過VMRuntime.getFinalizerTimeoutMs獲取,默認(rèn)值是10s.

超時檢測

通過watchdog機(jī)制檢測finalizer在超時時間內(nèi)有沒有成功析構(gòu)回收對象

Step1 GC前的檢查

開啟回收之前,needToWork會被置為true,此時sleepUntilNeeded返回的是true,所以線程不會wait

如果此時線程處于wait,被中斷了或者有OOME發(fā)生時,這個時候回到開頭判斷下isRunning(),也就是看下回收對象這個線程是否為空,如果該線程為空的話,這個循環(huán)體就沒有必要再繼續(xù)執(zhí)行下去了。

Step2 等待GC完成

這一步是等待回收結(jié)束的過程,這個睡眠過程中如果被中斷,說明在這個周期內(nèi)完成了析構(gòu),直接返回null

sleepForNanos對應(yīng)的函數(shù)很簡單,如果在超時時間內(nèi)完成GC,就會計算傳進(jìn)來的超時閾值減去當(dāng)前已經(jīng)睡眠的時間,如果這個差值小于0,說明睡眠的時間超過了閾值。

Step3 GC處理超時

如果第二步中的超時時間內(nèi)析構(gòu)沒有完成,則返回析構(gòu)的對象,觸發(fā)finalizerTimedOut。
到了這一步是最不希望看到的結(jié)局,此時系統(tǒng)會彈出應(yīng)用停止運(yùn)行的報錯框。

注意這個時候并沒有立刻殺死進(jìn)程,殺死進(jìn)程的選擇權(quán)交給了用戶,即通過彈窗展示給用戶,但對于用戶來說會一頭霧水

分析結(jié)論

這種問題其實(shí)還是比較常見的,特別是低內(nèi)存的機(jī)器上。RootCasue就是對象回收超時了,一般是由于隊列中等待FinalizerDaemon線程回收的對象太多導(dǎo)致,或者此時系統(tǒng)資源異常緊張比如CPU負(fù)載過高或者低內(nèi)存環(huán)境下。

場景實(shí)測

模擬還原現(xiàn)場

通過模擬GC時耗時操作,應(yīng)用退到后臺后10s會彈出報錯框,堆棧如下

驗(yàn)證了超時時間的確是10s,同時也驗(yàn)證了GC時耗時的操作確實(shí)會可能觸發(fā)這個現(xiàn)象

對比機(jī)情況

在手頭的小米note9 pro上進(jìn)行場景模擬測試,模擬GC耗時100s的情況

在小米的機(jī)器上,到了默認(rèn)的10s后并不會有彈窗,說明小米肯定修改了超時時間,第一次是等待了全部的100s后竟然正?;厥?,說明超時時間設(shè)置的比較大。緊接著下一次在達(dá)到了近80s時,進(jìn)程收到signal 9直接被kill了,此時再點(diǎn)擊應(yīng)用是冷啟動。

小米修改了超時閾值(超過100s),通過直接sig 9殺掉了進(jìn)程,沒有報錯彈窗,所以用戶無感知

測試機(jī)情況

同樣的在我們的機(jī)器上模擬GC耗時100s的情況
退出應(yīng)用到后臺,此時系統(tǒng)觸發(fā)GC回收,達(dá)到十秒鐘時,界面上直接彈出停止運(yùn)行的報錯框,此時只有點(diǎn)擊了關(guān)閉應(yīng)用,才會去kill進(jìn)程

修改策略

在GC規(guī)定的超時時間內(nèi)如果沒有完成析構(gòu),直接sig 9給對應(yīng)進(jìn)程


突然彈出王者榮耀停止運(yùn)行,GC超時導(dǎo)致的后臺應(yīng)用崩潰問題分析的評論 (共 條)

分享到微博請遵守國家法律
金乡县| 会理县| 乾安县| 库伦旗| 桐庐县| 上蔡县| 鹤岗市| 五华县| 台中市| 微博| 南京市| 高唐县| 新余市| 天津市| 高邮市| 东港市| 横山县| 福鼎市| 东海县| 遂川县| 安丘市| 麻江县| 井陉县| 阳信县| 建平县| 浮山县| 定远县| 泰顺县| 巴塘县| 阳朔县| 泊头市| 时尚| 西昌市| 清水河县| 河津市| 南部县| 扎鲁特旗| 利川市| 兴宁市| 寿宁县| 莱芜市|