Android Bitmap 內(nèi)存以及OOM問題討論

都知道在Android中, 每個(gè)應(yīng)用所使用的內(nèi)存是有限的,現(xiàn)在的手機(jī)通常最大的內(nèi)存使用為256M, 目前還沒發(fā)現(xiàn)Android中一個(gè)應(yīng)用的最大內(nèi)存分配超過256M的(經(jīng)測(cè)試華為手機(jī)的最大內(nèi)存是385M)

相關(guān)API:

ActivityManager.getMemoryClass(),首先獲取系統(tǒng)服務(wù)中的ActivityManager

如下:

(ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);

可以獲取到相關(guān)信息

最近一直被項(xiàng)目的OOM問題困擾, 在網(wǎng)上查閱相關(guān)資料,前前后后讀了不下于30篇,這些篇幅講解的東西都是千篇一律,并沒有解決到實(shí)際問題

也在慕課網(wǎng)學(xué)習(xí)了內(nèi)存優(yōu)化章節(jié)


這是慕課網(wǎng)講師的PPT,我截屏的

這里來仔細(xì)分析一下:

第一個(gè), ?注意臨時(shí)Bitmap對(duì)象的及時(shí)回收, 來看下相關(guān)API

直接上圖


經(jīng)過我無數(shù)次的使用Android studio工具自帶的MAT分析工具后, 得出一個(gè)很嚴(yán)謹(jǐn)?shù)慕Y(jié)論, 此方法并不奏效...

Android中Bitmap的內(nèi)存存放在堆區(qū), Google 的Bitmap的recycle方法注釋也可以了解到

Android歷史版本不是很清楚, 據(jù)說Android3.0之前Bitmap是存放在native區(qū)域,可以進(jìn)行手動(dòng)釋放,然而3.0之后Bitmap是存放在Java層的堆區(qū),沒錯(cuò)是heap, 內(nèi)存管理直接交由系統(tǒng)GC管理,你還這樣釋放資源有意義?無非是給自己的一點(diǎn)心理安慰罷了, 告訴你沒卵用

又有人在說要釋放內(nèi)存使用System.gc() ??? ?對(duì)就是主動(dòng)觸發(fā)垃圾回收,這個(gè)API是開發(fā)者自行調(diào)用的嗎?那么系統(tǒng)管理內(nèi)存還有什么意義?這不是誤人子弟嗎,這個(gè)API不能調(diào)用的, 因?yàn)闆]卵用的, 具體自己參照MAT工具自行分析.即便垃圾回收真的被觸發(fā)了, 所有線程停滯由系統(tǒng)來清理垃圾, 造成的后果是嚴(yán)重卡頓!!!

再看一個(gè)API:


我在網(wǎng)上苦苦追尋內(nèi)存過高的問題后,發(fā)現(xiàn)了這個(gè)API,經(jīng)過無數(shù)次實(shí)踐后我得出一個(gè)結(jié)論,沒卵用...開發(fā)者可以拋棄它

綜上所訴, 第一點(diǎn)講解的內(nèi)存優(yōu)化問題可以直接PASS掉, 無非給自己一點(diǎn)心理安慰: 我已經(jīng)處理好了內(nèi)存問題, 程序不會(huì)OOM?

第二點(diǎn). 避免Bitmap的浪費(fèi)

直接說結(jié)論, 這個(gè)是非常行之有效的,并且是一定能解決問題的

具體怎么操作呢? 自己實(shí)現(xiàn)LruCache這個(gè)類, 就是這么弄, 原理就是解碼復(fù)用, 在內(nèi)存中已經(jīng)解碼好的Bitmap直接拿出來使用, 沒有的在加載到內(nèi)存進(jìn)行解析, 這個(gè)非常有效,但是并不能讓你避免OOM

第三點(diǎn), try-catch某些大內(nèi)存分配的操作

這點(diǎn)上,我又要開始疑問了, 我Java功底不是很好

Java中發(fā)生內(nèi)存溢出時(shí),拋出的是OutOfMemoryError, 它的父類是VirtualMachineError

這玩意能catch住? 它屬于Error范疇, 你能捕獲?請(qǐng)Java大神出來說一下,我解釋不清楚

第四點(diǎn), 加載Bitmap 縮放比例, 解碼格式, 局部加載

先來分析一下縮放比例:

按照市面上主流的手機(jī)分辨率來分析現(xiàn)在Android主流的分辨率是1920X1080, 如果一個(gè)ImageView控件剛好就是屏幕全屏,怎么說?直接占用掉8M內(nèi)存, 想想一個(gè)實(shí)際的需求情況

一個(gè)查看大圖的頁面, 不斷的關(guān)閉,打開查看新的大圖,問題就來了,內(nèi)存一直在暴增,遲早會(huì)突破界限OOM掉

分辨率是2K屏呢? 更恐怖了, 隨著手機(jī)設(shè)備的屏幕分辨率提升, 加載圖像需要的內(nèi)存也是倍增的, 因?yàn)閼?yīng)用的最大內(nèi)存并沒有增加

結(jié)論: 縮放比例可以有效的降低內(nèi)存占用問題, 但不是絕對(duì)的救命稻草, 該縮放的還是要縮放,而且必須縮放,就是采樣 ?現(xiàn)在通常都是圖片加載框架來完成,類似Glide.Picasso,Fresco等,他們可以幫助你減少工作量, 內(nèi)存問題還是存在

再來分析一下解碼格式:

這個(gè)跟縮放比例效果差不多, 只是同樣的分辨率的圖片加載到內(nèi)存中時(shí)占用內(nèi)存減少了

比如ARGB_8888 共32位

RGB_565 ?共16位

ARGB_4444 共16位

很明顯這樣格式圖片加載的內(nèi)存情況是ARGB_8888是其他格式的兩倍內(nèi)存

另外的問題是ARGB_8888看起來很清晰的, 其它的看起來圖片有種糊了的感覺,自己選擇吧

結(jié)論, 降低內(nèi)存占用非常有效

最后一個(gè)是局部加載, 并沒有怎么使用到,也不清楚就不說了

最后還有一個(gè)方法避免OOM, 開啟largeHeap屬性, 但是但是, 以前我們開啟這個(gè)屬性后被Oppo應(yīng)用市場(chǎng)認(rèn)定為占用內(nèi)存過高, 不建議用戶安裝......所以我們又取消了!

總的來說, Bitmap在內(nèi)存是變現(xiàn)的是不可控, 我項(xiàng)目OOM問題一直沒有得到有效解決,因?yàn)閳D片編輯視頻編輯之類的功能占用內(nèi)存過高,繼續(xù)使用OOM是必然的, 跟IOS的同學(xué)交流了一番,他們說IOS的應(yīng)用內(nèi)存可以占用到1個(gè)G以上, 輕松跑到500M是沒問題的, IOS的內(nèi)存機(jī)制可以持續(xù)給內(nèi)存使用, 具體我也不清楚,并且他們可以手動(dòng)釋放內(nèi)存?malloc, free這樣子?

如果大家有比較好的方案,還望留言交流互相幫助 [笑臉.gif]

補(bǔ)充: Android8.0開始Bitmap數(shù)據(jù)內(nèi)存存在native層, 單個(gè)應(yīng)用可用的內(nèi)存顯著增長(zhǎng), 極大的降低了OOM的概率(2018年3月22日)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末笙瑟,一起剝皮案震驚了整個(gè)濱河市魔种,隨后出現(xiàn)的幾起案子盐须,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件咐汞,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)墩划,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來嗡综,“玉大人乙帮,你說我怎么就攤上這事「蚋撸” “怎么了蚣旱?”我有些...
    開封第一講書人閱讀 162,823評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)戴陡。 經(jīng)常有香客問我塞绿,道長(zhǎng),這世上最難降的妖魔是什么恤批? 我笑而不...
    開封第一講書人閱讀 58,204評(píng)論 1 292
  • 正文 為了忘掉前任异吻,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘诀浪。我一直安慰自己棋返,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評(píng)論 6 388
  • 文/花漫 我一把揭開白布雷猪。 她就那樣靜靜地躺著睛竣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪求摇。 梳的紋絲不亂的頭發(fā)上射沟,一...
    開封第一講書人閱讀 51,190評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音与境,去河邊找鬼验夯。 笑死,一個(gè)胖子當(dāng)著我的面吹牛摔刁,可吹牛的內(nèi)容都是我干的挥转。 我是一名探鬼主播,決...
    沈念sama閱讀 40,078評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼共屈,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼绑谣!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起趁俊,我...
    開封第一講書人閱讀 38,923評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤域仇,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后寺擂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體暇务,經(jīng)...
    沈念sama閱讀 45,334評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評(píng)論 2 333
  • 正文 我和宋清朗相戀三年怔软,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了垦细。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,727評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡挡逼,死狀恐怖括改,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情家坎,我是刑警寧澤嘱能,帶...
    沈念sama閱讀 35,428評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站虱疏,受9級(jí)特大地震影響惹骂,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜做瞪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評(píng)論 3 326
  • 文/蒙蒙 一对粪、第九天 我趴在偏房一處隱蔽的房頂上張望右冻。 院中可真熱鬧,春花似錦著拭、人聲如沸纱扭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽乳蛾。三九已至,卻和暖如春鄙币,著一層夾襖步出監(jiān)牢的瞬間屡久,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評(píng)論 1 269
  • 我被黑心中介騙來泰國打工爱榔, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人糙及。 一個(gè)月前我還...
    沈念sama閱讀 47,734評(píng)論 2 368
  • 正文 我出身青樓详幽,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親浸锨。 傳聞我的和親對(duì)象是個(gè)殘疾皇子唇聘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容