Android中內存優化的那些事 - 一個有關圖片的優化記錄

客服群里叫喊著:這個用戶圖片不顯示了,那個用戶圖片也不顯示了。我拿著手上一切正常的測試機,what the hell……

默默地打開bugly。




滿園春色關不住,遍地內存溢出來!是的,又闖禍了!

內存問題永遠是既陌生又熟悉的話題,而且大多數都發生在一個叫作用戶家的手機上。安卓系統本身不斷的在優化,三方框架也逐漸成熟,外加手機廠商的大內存加持,似乎內存問題變得少見,但還是不能忽視。

借著這次修復內存問題的記錄,分享一些“自以為”的解決思路,僅供參考。ok,let’s go!

修復問題的三部曲,先復現,再定位,最后修復。

復現

估計有的人會說,異?,F象都在那,有啥好復現的,沖進代碼直接開干。

修復bug永遠是個驚心動魄的事,稍微一不小心就有可能天崩地裂。不是修復不完全,就是引入新問題。從起因開始了解整個緣由,一方面能加深對問題的理解,同時確保最終能驗證問題是否得到修復。

內存的問題經常發生在一些比較特殊的環境下,而且很多時候不一定是必現,往往體現在一些中低端機型上。所以從機型上入手可能會是一個不錯的選擇。

最終,通過bugly查到了對應的問題機型及系統版本,上各類云測平臺找到了臺云測試機。按照進入問題頁面的幾個固定流程,反復執行,最終鎖定了復現流程。

定位

知道問題如何復現,接下來就是定位問題到底出在哪。通常內存的問題,會碰到兩種情況:

  1. 內存堆積:由于特殊情況造成的頁面關閉但資源還遺漏在內存中。
  2. 內存高占用:由于業務需要或者使用不當導致內存占用量過高。

我們先來看看這次的問題屬于哪種情況。

在Android Studio2.3及之前版本上自帶的Android monitor中,可以直觀的反應出當前應用的整體內存使用水平。[如何使用工具的分享估計大家都看膩了,這次就不再重復了。]

142MB!?。?!進入事故現場之前就已經被占用了這么多內存。難怪之后會內存異常。看來這次要先解決內存高占用的問題,我們先要詳細的了解內存的具體情況,才知道從哪下手去解決,無論是避免無意義的使用或者優化必要的占用。

先強制gc一下,然后dump java heap,看一下整體內存里的情況,按照shallow size排序。

首當其沖的byte數組映入眼簾,大家都明白的,bitmap一直都是大客戶。我們接著分析下byte[]中的各個對象。

從數據上看,有很多大小相同的內存使用,從理論上看應該是有很多尺寸相同的圖片??蔀槭裁磿羞@么多呢?是相同的圖片重復了?or other?

所謂耳聽為虛眼見為實,如果能看到這些圖片長什么樣,是否就容易做出對應的判斷了?來,開始行動:
來自Gracker的Android內存優化之三:打開MAT中的Bitmap原圖 | Performance

感謝Gracker的分享,Get到一個新技能。具體流程參見傳送門。主體思路就是通過MAT將對應的byte數組另存為圖片原始文件,再用對應的工具打開預覽即可。不過我記得以前Android Studio是可以直接看的,可現在不知道跑哪了。

步驟一:

因為Android Studio dump出來的文件mat是無法直接打開的,所以需要做一次轉換。在Captures中找到剛剛dump出來的prof文件。右鍵 -> Export to standar .hprof 即可。

步驟二:

通過MAT Eclipse Memory Analyzer Open Source Project 打開。

步驟三:

右鍵想要查看的對象 -> Copy -> Save Value To File。保存為xxx.data。他推薦使用Gracker分享中的gimp。Photoshop不確定是不是我使用方式有問題,在驗證的時候一直無法正常顯示。

步驟四:

查看對應圖片的相關屬性,主體是要寬高,因為上一步中保存的是圖片的原始格式文件,其中不包含對應的參數信息,所以在導入gimp中需要指定對應的參數。

步驟五:

打開gimp GIMP - Downloads. 然后打開剛剛導出的問題。圖像類型根據實際的來,一般都是8888或者565,選擇RGB Alpha或者RGB565。然后寬度與高度填寫剛剛查詢到的參數。最后點擊open就能看到實際的圖片。

通過這個方式,可以直觀的查看到內存中圖片的實際情況。然后我們就可以進一步分析產生問題的實際原因。

通過以上方式,定位到了3個問題:

  1. 有大量圖片資源占用,首頁確實有好多圖。
  2. 有暫未使用到的圖片資源占用(gone狀態)。
  3. 有大量蒙版圖片占用,因為設計師要求的效果。

解決 - 大量圖片占用

對于大量圖片占用的問題,其實從以下幾個個方向來看思考問題。

  1. 從效果設計的角度來避免,盡可能的少使用滿屏圖片的方式來處理需求。但這方面我個人主張尊重設計師,專業的事情交給專業的人去處理。
  2. 圖片資源本身,在滿足效果的前提下,盡可能的選用RGB565,也許少量圖片不明顯,但在量大的情況下,節省的內存資源還是很客觀。
  3. 圖片資源在不使用的時候及時釋放。

結合以上方向來看下我們遇到的問題。設計角度目前無法調整,緣由都是淚,這里就不多說了。資源本身已經是RGB565。圖片的釋放應該是fresco的強項,可從現象上看似乎并沒有??磥韱栴}可能出在這,回ui頁面上瞄一眼,明白了。

viewpager + fragment + recyclerview,相當于大量圖片都屬于使用狀態,所以fresco不會去釋放對應的資源。

臨時解決方案:
為了確保核心邏輯的順利,通過RxBus的方式,在進入和退出核心頁面時發送Event事件,然后在大量使用圖片的頁面注冊接收此系列事件,遍歷所有SimpleDraweeView,調用其Controller的onDetach或onAttach來,從而實現圖片資源引用的臨時釋放和加載恢復。

為什么是臨時解決方案,因為我總覺得是一種取巧的方式,理論上看。是不應該直接調用方法來插手fresco的管理流程。所以此處留坑,之后再次深入了解fresco的原理后再回填,也希望大家提些建議或者意見。

解決 - 暫未使用到的圖片資源占用

每個頁面中,都有處理網絡異常及相關數據加載異常的提示。原先的處理方式是通過include統一導入后隱藏,在遇到異常的時候才顯示出來。問題就出在這,這些異常提示本身是小概率觸發,但通過include標簽導入的話,會直接實例化完成,占用內存資源。

臨時解決方案:
改用ViewStub標簽,實現按需加載。

為什么又是臨時解決方案呢,因為有些機型在黑屏狀態下是切斷wifi的,當重新進入應用的時候都會經過一個聯網的過程,所以會先觸發聯網異常,ViewStub只能加載一次,加載完后就占用內存了。

解決 - 蒙版圖片

之前為了在圖片上顯示文字但又不想被圖案所影響,所以在上面加一層陰影蒙版來保證字體的顯示效果。習慣用fresco:overlayImage的方法來實現。但這種實現方式會造成蒙版本身是一個獨立的內存資源。

解決方法:
嘗試通過Processor的方式,預先把蒙版與要顯示的圖片合成,使得在內存中只保留一份資源。

結果

通過以上優化方式,同樣的機型再次檢測,內存占用下來了....

總結

這次從內存高占用入手,解決了由于內存使用量過高導致的內存溢出。等之后遇到內存遺留問題時,再來補下文。

內存問題的排查與解決算是一個老生常談的話題,因為適配等等情況往往又是一個比較棘手的問題。開發的時候很難發現,所以建議一個需求完成后都例行的檢查下內存狀況,看下是否有問題后者需要調整的部分。

原文鏈接: Android中內存優化的那些事 - 一個有關圖片的優化記錄

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,694評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,672評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,965評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,690評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,019評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,188評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,718評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,438評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,667評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,845評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,252評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,590評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,384評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容