自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Android中內(nèi)存優(yōu)化的那些事 - 一個(gè)有關(guān)圖片的優(yōu)化記錄

移動(dòng)開(kāi)發(fā) Android
內(nèi)存問(wèn)題永遠(yuǎn)是既陌生又熟悉的話題,而且大多數(shù)都發(fā)生在一個(gè)叫作用戶家的手機(jī)上。安卓系統(tǒng)本身不斷的在優(yōu)化,三方框架也逐漸成熟,外加手機(jī)廠商的大內(nèi)存加持,似乎內(nèi)存問(wèn)題變得少見(jiàn),但還是不能忽視。

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

默默地打開(kāi)bugly。

  

 

 

滿園春色關(guān)不住,遍地內(nèi)存溢出來(lái)!是的,又闖禍了!

內(nèi)存問(wèn)題永遠(yuǎn)是既陌生又熟悉的話題,而且大多數(shù)都發(fā)生在一個(gè)叫作用戶家的手機(jī)上。安卓系統(tǒng)本身不斷的在優(yōu)化,三方框架也逐漸成熟,外加手機(jī)廠商的大內(nèi)存加持,似乎內(nèi)存問(wèn)題變得少見(jiàn),但還是不能忽視。

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

修復(fù)問(wèn)題的三部曲,先復(fù)現(xiàn),再定位,***修復(fù)。

復(fù)現(xiàn)

估計(jì)有的人會(huì)說(shuō),異?,F(xiàn)象都在那,有啥好復(fù)現(xiàn)的,沖進(jìn)代碼直接開(kāi)干。

修復(fù)bug永遠(yuǎn)是個(gè)驚心動(dòng)魄的事,稍微一不小心就有可能天崩地裂。不是修復(fù)不完全,就是引入新問(wèn)題。從起因開(kāi)始了解整個(gè)緣由,一方面能加深對(duì)問(wèn)題的理解,同時(shí)確保最終能驗(yàn)證問(wèn)題是否得到修復(fù)。

內(nèi)存的問(wèn)題經(jīng)常發(fā)生在一些比較特殊的環(huán)境下,而且很多時(shí)候不一定是必現(xiàn),往往體現(xiàn)在一些中低端機(jī)型上。所以從機(jī)型上入手可能會(huì)是一個(gè)不錯(cuò)的選擇。

最終,通過(guò)bugly查到了對(duì)應(yīng)的問(wèn)題機(jī)型及系統(tǒng)版本,上各類(lèi)云測(cè)平臺(tái)找到了臺(tái)云測(cè)試機(jī)。按照進(jìn)入問(wèn)題頁(yè)面的幾個(gè)固定流程,反復(fù)執(zhí)行,最終鎖定了復(fù)現(xiàn)流程。

定位

知道問(wèn)題如何復(fù)現(xiàn),接下來(lái)就是定位問(wèn)題到底出在哪。通常內(nèi)存的問(wèn)題,會(huì)碰到兩種情況:

  1. 內(nèi)存堆積:由于特殊情況造成的頁(yè)面關(guān)閉但資源還遺漏在內(nèi)存中。
  2. 內(nèi)存高占用:由于業(yè)務(wù)需要或者使用不當(dāng)導(dǎo)致內(nèi)存占用量過(guò)高。

我們先來(lái)看看這次的問(wèn)題屬于哪種情況。

在Android Studio2.3及之前版本上自帶的Android monitor中,可以直觀的反應(yīng)出當(dāng)前應(yīng)用的整體內(nèi)存使用水平。[如何使用工具的分享估計(jì)大家都看膩了,這次就不再重復(fù)了。

 

142MB!!!!進(jìn)入事故現(xiàn)場(chǎng)之前就已經(jīng)被占用了這么多內(nèi)存。難怪之后會(huì)內(nèi)存異常??磥?lái)這次要先解決內(nèi)存高占用的問(wèn)題,我們先要詳細(xì)的了解內(nèi)存的具體情況,才知道從哪下手去解決,無(wú)論是避免無(wú)意義的使用或者優(yōu)化必要的占用。

先強(qiáng)制gc一下,然后dump java heap,看一下整體內(nèi)存里的情況,按照shallow size排序。

 

首當(dāng)其沖的byte數(shù)組映入眼簾,大家都明白的,bitmap一直都是大客戶。我們接著分析下byte[]中的各個(gè)對(duì)象。

 

從數(shù)據(jù)上看,有很多大小相同的內(nèi)存使用,從理論上看應(yīng)該是有很多尺寸相同的圖片??蔀槭裁磿?huì)有這么多呢?是相同的圖片重復(fù)了?or other?

所謂耳聽(tīng)為虛眼見(jiàn)為實(shí),如果能看到這些圖片長(zhǎng)什么樣,是否就容易做出對(duì)應(yīng)的判斷了?來(lái),開(kāi)始行動(dòng):

來(lái)自Gracker的Android內(nèi)存優(yōu)化之三:打開(kāi)MAT中的Bitmap原圖 | Performance。

感謝Gracker的分享,Get到一個(gè)新技能。具體流程參見(jiàn)傳送門(mén)。主體思路就是通過(guò)MAT將對(duì)應(yīng)的byte數(shù)組另存為圖片原始文件,再用對(duì)應(yīng)的工具打開(kāi)預(yù)覽即可。不過(guò)我記得以前Android Studio是可以直接看的,可現(xiàn)在不知道跑哪了。

步驟一:

因?yàn)锳ndroid Studio dump出來(lái)的文件mat是無(wú)法直接打開(kāi)的,所以需要做一次轉(zhuǎn)換。在Captures中找到剛剛dump出來(lái)的prof文件。右鍵 -> Export to standar .hprof 即可。

 

步驟二:

通過(guò)MAT Eclipse Memory Analyzer Open Source Project 打開(kāi)。

 

步驟三:

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

 

步驟四:

查看對(duì)應(yīng)圖片的相關(guān)屬性,主體是要寬高,因?yàn)樯弦徊街斜4娴氖菆D片的原始格式文件,其中不包含對(duì)應(yīng)的參數(shù)信息,所以在導(dǎo)入gimp中需要指定對(duì)應(yīng)的參數(shù)。

 

步驟五:

打開(kāi)gimp GIMP - Downloads. 然后打開(kāi)剛剛導(dǎo)出的問(wèn)題。圖像類(lèi)型根據(jù)實(shí)際的來(lái),一般都是8888或者565,選擇RGB Alpha或者RGB565。然后寬度與高度填寫(xiě)剛剛查詢到的參數(shù)。***點(diǎn)擊open就能看到實(shí)際的圖片。

 

 

通過(guò)這個(gè)方式,可以直觀的查看到內(nèi)存中圖片的實(shí)際情況。然后我們就可以進(jìn)一步分析產(chǎn)生問(wèn)題的實(shí)際原因。

通過(guò)以上方式,定位到了3個(gè)問(wèn)題:

  1. 有大量圖片資源占用,首頁(yè)確實(shí)有好多圖。
  2. 有暫未使用到的圖片資源占用(gone狀態(tài))。
  3. 有大量蒙版圖片占用,因?yàn)樵O(shè)計(jì)師要求的效果。

解決 - 大量圖片占用

對(duì)于大量圖片占用的問(wèn)題,其實(shí)從以下幾個(gè)個(gè)方向來(lái)看思考問(wèn)題。

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

結(jié)合以上方向來(lái)看下我們遇到的問(wèn)題。設(shè)計(jì)角度目前無(wú)法調(diào)整,緣由都是淚,這里就不多說(shuō)了。資源本身已經(jīng)是RGB565。圖片的釋放應(yīng)該是fresco的強(qiáng)項(xiàng),可從現(xiàn)象上看似乎并沒(méi)有??磥?lái)問(wèn)題可能出在這,回ui頁(yè)面上瞄一眼,明白了。

viewpager + fragment + recyclerview,相當(dāng)于大量圖片都屬于使用狀態(tài),所以fresco不會(huì)去釋放對(duì)應(yīng)的資源。

臨時(shí)解決方案:

為了確保核心邏輯的順利,通過(guò)RxBus的方式,在進(jìn)入和退出核心頁(yè)面時(shí)發(fā)送Event事件,然后在大量使用圖片的頁(yè)面注冊(cè)接收此系列事件,遍歷所有SimpleDraweeView,調(diào)用其Controller的onDetach或onAttach來(lái),從而實(shí)現(xiàn)圖片資源引用的臨時(shí)釋放和加載恢復(fù)。

為什么是臨時(shí)解決方案,因?yàn)槲铱傆X(jué)得是一種取巧的方式,理論上看。是不應(yīng)該直接調(diào)用方法來(lái)插手fresco的管理流程。所以此處留坑,之后再次深入了解fresco的原理后再回填,也希望大家提些建議或者意見(jiàn)。

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

每個(gè)頁(yè)面中,都有處理網(wǎng)絡(luò)異常及相關(guān)數(shù)據(jù)加載異常的提示。原先的處理方式是通過(guò)include統(tǒng)一導(dǎo)入后隱藏,在遇到異常的時(shí)候才顯示出來(lái)。問(wèn)題就出在這,這些異常提示本身是小概率觸發(fā),但通過(guò)include標(biāo)簽導(dǎo)入的話,會(huì)直接實(shí)例化完成,占用內(nèi)存資源。

臨時(shí)解決方案:

改用ViewStub標(biāo)簽,實(shí)現(xiàn)按需加載。

為什么又是臨時(shí)解決方案呢,因?yàn)橛行C(jī)型在黑屏狀態(tài)下是切斷wifi的,當(dāng)重新進(jìn)入應(yīng)用的時(shí)候都會(huì)經(jīng)過(guò)一個(gè)聯(lián)網(wǎng)的過(guò)程,所以會(huì)先觸發(fā)聯(lián)網(wǎng)異常,ViewStub只能加載一次,加載完后就占用內(nèi)存了。

解決 - 蒙版圖片

之前為了在圖片上顯示文字但又不想被圖案所影響,所以在上面加一層陰影蒙版來(lái)保證字體的顯示效果。習(xí)慣用fresco:overlayImage的方法來(lái)實(shí)現(xiàn)。但這種實(shí)現(xiàn)方式會(huì)造成蒙版本身是一個(gè)獨(dú)立的內(nèi)存資源。

解決方法:

嘗試通過(guò)Processor的方式,預(yù)先把蒙版與要顯示的圖片合成,使得在內(nèi)存中只保留一份資源。

結(jié)果

通過(guò)以上優(yōu)化方式,同樣的機(jī)型再次檢測(cè),內(nèi)存占用下來(lái)了....

 

總結(jié)

這次從內(nèi)存高占用入手,解決了由于內(nèi)存使用量過(guò)高導(dǎo)致的內(nèi)存溢出。等之后遇到內(nèi)存遺留問(wèn)題時(shí),再來(lái)補(bǔ)下文。

內(nèi)存問(wèn)題的排查與解決算是一個(gè)老生常談的話題,因?yàn)檫m配等等情況往往又是一個(gè)比較棘手的問(wèn)題。開(kāi)發(fā)的時(shí)候很難發(fā)現(xiàn),所以建議一個(gè)需求完成后都例行的檢查下內(nèi)存狀況,看下是否有問(wèn)題后者需要調(diào)整的部分。 

責(zé)任編輯:龐桂玉 來(lái)源: Android技術(shù)之家
相關(guān)推薦

2015-09-08 14:42:17

Android性能優(yōu)化

2015-07-23 09:30:43

爛代碼程序員

2013-09-16 16:56:09

AndroidBitmap內(nèi)存優(yōu)化

2012-06-19 13:15:58

WANSharePoint

2018-07-05 09:25:07

系統(tǒng)存儲(chǔ)層次

2022-04-08 09:47:55

性能優(yōu)化開(kāi)發(fā)

2022-09-15 08:33:11

ChaosBladeJava場(chǎng)景

2016-12-20 10:59:43

MySQL存儲(chǔ)insert

2017-02-14 17:00:39

iOSApp內(nèi)存優(yōu)化

2020-05-20 13:24:28

MySQL優(yōu)化數(shù)據(jù)庫(kù)

2021-08-11 21:46:47

MySQL索引join

2017-03-08 08:53:44

Git命令 GitHub

2019-07-15 15:37:31

頁(yè)面緩存內(nèi)存

2021-05-17 08:18:35

Java內(nèi)存模型JMM

2011-07-21 16:40:28

網(wǎng)站優(yōu)化

2015-08-27 17:08:46

大數(shù)據(jù)

2017-03-14 18:48:06

Android性能優(yōu)化內(nèi)存優(yōu)化

2023-02-23 12:15:05

2014-03-27 11:34:09

C#優(yōu)化性能優(yōu)化

2018-04-09 08:55:05

LinuxWindows頁(yè)面緩存
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)