問題背景
?近期測試同學(xué)反饋了兩臺機器不開機問題阿浓,一直定住在動態(tài)開機動畫界面疲陕,重啟設(shè)備后問題依然必現(xiàn)墓赴。問題有點不可思議,正常情況下渗钉,大部分此類問題在重啟設(shè)備后應(yīng)該會破壞現(xiàn)象的彤恶。對于必現(xiàn)問題,那就很慶幸晌姚,可以隨便折騰分析粤剧,有此果必有起因。
分析思路
-
抓取開機Log
首先根據(jù)main log信息挥唠,看到系統(tǒng)頻繁在GC操作抵恋,以及其他進程不斷被LowMemroyKiller,以下列出部分關(guān)鍵信息:
lowmemorykiller.png
?當卡住在動畫界面后宝磨,系統(tǒng)不再輸出log弧关,看上去就是定屏現(xiàn)象了,根據(jù)如上信息唤锉,懷疑是系統(tǒng)可用內(nèi)存不足世囊,導(dǎo)致了這一系列問題,但正常開機流程是不可能出現(xiàn)這種現(xiàn)象的哇窿祥。為了驗證懷疑株憾,還是用數(shù)據(jù)證明,有時候不能按照常理來解釋晒衩。重啟設(shè)備嗤瞎,不斷執(zhí)行dumpsys meminfo命令,實時輸出內(nèi)存信息听系。
?一看嚇一跳贝奇,system_server進程在開機過程中竟然達到400M左右,正常是在100M左右的靠胜。
-
DDMS+MAT分析內(nèi)存溢出
?System_server進程內(nèi)存溢出了掉瞳,使用DDMS抓取system_server進程的內(nèi)存使用情況毕源,導(dǎo)出hprof格式文件。然后使用MAT來分析抓取的堆存儲文件hprof陕习。
?MAT霎褐,全稱為Memory Analysis Tool,是對內(nèi)存進行詳細分析的工具衡查,它是Eclipse的插件瘩欺,如果用Android Studio進行開發(fā)則需要單獨下載它,下載地址為:http://eclipse.org/mat/拌牲。
-
DDMS生成hprof文件
?生成hpof文件主要分為以下幾個步驟:- 運行DDMS程序俱饿。
- 選擇system_server進程,點擊Update Heap按鈕塌忽,開始進行追蹤拍埠。
- 發(fā)生內(nèi)存溢出后,點擊Dump HPROP File按鈕結(jié)束追蹤土居,生成并保存hprof文件枣购,如下圖所示。
DDMS生成的hprof文件并不是標準的擦耀,還需要將它轉(zhuǎn)換為標準的hprof文件棉圈,這樣才會被MAT識別從而進行分析,可以使用Android SDK自帶的hprof-conv進行轉(zhuǎn)換眷蜓,路徑在sdk/platform-tools中分瘾,進入到該路徑執(zhí)行以下語句即可:
./hprof-conv '/home/wangjiaxi/will_one/wjx_log/l2_h/scan/64/11/hang/hprof/p2_pro_hprof/system_process.hprof' /home/wangjiaxi/will_one/wjx_log/l2_h/scan/64/11/hang/hprof/p2_pro_hprof/hprof/p2pro.hprof
- MAT分析hprof文件
?用MAT打開標準的hpof文件,選擇Leak Suspects Report選項吁系。這時MAT就會生成報告德召,如下圖所示。
結(jié)果顯示汽纤,加載一個Bitmap對象時上岗,內(nèi)存竟然分配了150M,實在太可怕了
- 結(jié)合代碼分析跟因
?Bitmap分配了150M內(nèi)存蕴坪,哪能分配這么大呢肴掷?
在細看main log信息,發(fā)現(xiàn)了一些貓膩背传,系統(tǒng)的density匪夷所思為30000捆等,設(shè)備是720X1280,應(yīng)該為320dpi才對续室。這個數(shù)值相差太大了。
原來該設(shè)備rom版本開放了修改density接口給云端谒养,云端配置了density 30000推送修改了display_density_forced這個setting字段挺狰。
?至于為什么density修改了30000后明郭,一張Bitmap占用的內(nèi)存會達到150M呢,這就需要跟蹤Graphic系統(tǒng)的skia代碼丰泊,這里是最終計算一張圖片加載的時候系統(tǒng)分配內(nèi)存大小薯定。
后續(xù)會寫一篇關(guān)于這個Bitmap如何到底分配多大內(nèi)存的文章。
將density設(shè)置到正常值后瞳购,重啟開機即可恢復(fù)正常狀態(tài)话侄,所以不要濫用設(shè)置density數(shù)值,會影響資源加載時內(nèi)存分配情況学赛。