Bitmap有沒有必要主動recycle的問題

大家都知道吗伤,Android開發(fā)中,如果涉及到大量bitmap的處理硫眨,一個不小心就會發(fā)生OOM足淆。所以,對我來說礁阁,當bitmap對象不再需要的時候巧号,及時recycle掉,幾乎是常識一樣自然的事情姥闭。
去年做一個項目的時候棚品,剛好讓控件組的同事看了一下我的代碼。他說他們組做過測試骡澈,感覺recycle沒什么用肋殴。不過控件用到的圖片相對都比較小护锤,所以也不好判斷蔽豺。
之后看了一下源碼修陡,是這么描述recycle的:

    /**
     * Free the native object associated with this bitmap, and clear the
     * reference to the pixel data. This will not free the pixel data synchronously;
     * it simply allows it to be garbage collected if there are no other references.
     * The bitmap is marked as "dead", meaning it will throw an exception if
     * getPixels() or setPixels() is called, and will draw nothing. This operation
     * cannot be reversed, so it should only be called if you are sure there are no
     * further uses for the bitmap. This is an advanced call, and normally need
     * not be called, since the normal GC process will free up this memory when
     * there are no more references to this bitmap.
     */
    public void recycle() {
        if (!mRecycled && mNativePtr != 0) {
            if (nativeRecycle(mNativePtr)) {
                // return value indicates whether native pixel object was actually recycled.
                // false indicates that it is still in use at the native level and these
                // objects should not be collected now. They will be collected later when the
                // Bitmap itself is collected.
                mBuffer = null;
                mNinePatchChunk = null;
            }
            mRecycled = true;
        }
    }

這是API 25的代碼,可以看到注釋里面有這么一句拾因,“This will not free the pixel data synchronously; it simply allows it to be garbage collected if there are no other references.”绢记。
我的理解就是蠢熄,recycle確實不是立即回收對應bitmap的內(nèi)存签孔,因為不是synchronously嘛饥追。

那么但绕,不調(diào)用recycle行嗎壁熄?

特別是上面的注釋里面寫了:

* This is an advanced call, and normally need
* not be called, since the normal GC process will free up this memory when
* there are no more references to this bitmap.

那么草丧,查了一些文檔后昌执,我的結(jié)論是:可以不調(diào)用recycle懂拾,但是要及時把對bitmap的引用置為null。至于以前都要求對bitmap主動recycle瓮孙,不要等GC杭抠,是有其歷史原因的偏灿。

我是通過這篇帖子 《Bitmap.recycle引發(fā)的血案 》http://www.reibang.com/p/b5c8e98ff5b0 找到了官方的兩個說明網(wǎng)頁:

https://developer.android.google.cn/topic/performance/graphics/manage-memory.html#recycle

https://developer.android.google.cn/topic/performance/graphics/cache-bitmap.html

而從上面的鏈接中铆遭,可以得到如下信息:

  1. Android中枚荣,Bitmap的對象在內(nèi)存中可以分為兩部分棍弄,一個是Bitmap對象本身呼畸,另一個是像素數(shù)據(jù)蛮原。
    并且儒陨,在Android 2.3.3 以前蹦漠,像素數(shù)據(jù)與對象本身分開存儲笛园,像素數(shù)據(jù)存儲在native層研铆;對象存儲在java層凶赁。顯然虱肄,像素數(shù)據(jù)才是內(nèi)存占用的大頭浩峡。并且翰灾,像素數(shù)據(jù)什么時候回收是沒有保證的纸淮。這時也是最容易觸發(fā) OOM 的時候咽块。
    但是侈沪,在Android 3.0 以后亭罪,像素數(shù)據(jù)與Bitmap對象數(shù)據(jù)一起關(guān)聯(lián)存儲在Dalvik堆中。所以箩祥,這個時候袍祖,就可以考慮用GC來自動回收Bitmap的內(nèi)存了盲泛。

On Android 2.3.3 (API level 10) and lower, the backing pixel data for a bitmap is stored in native memory. It is separate from the bitmap itself, which is stored in the Dalvik heap. The pixel data in native memory is not released in a predictable manner, potentially causing an application to briefly exceed its memory limits and crash. As of Android 3.0 (API level 11), the pixel data is stored on the Dalvik heap along with the associated bitmap.

  1. Android 2.2 中寺滚,GC發(fā)生的時候回造成應用線程停頓,也就是可能會卡蚁孔。
    但是杠氢,Android 2.3 里面更新了GC機制鼻百,應該不會再造成線程停止了温艇。

On Android Android 2.2 (API level 8) and lower, when garbage collection occurs, your app's threads get stopped. This causes a lag that can degrade performance. Android 2.3 adds concurrent garbage collection, which means that the memory is reclaimed soon after a bitmap is no longer referenced.

  1. 所以,作為完整性的結(jié)論琐鲁,官方說明是:
    a. Android 2.3.3 以前的版本围段,在確認Bitmap已經(jīng)不再使用的情況下,推薦主動調(diào)用recycle段磨。
    b. Android 3.0 以后砾隅,將Bitmap對象的引用及時置null就行了晴埂,應該不需要再主動調(diào)用recycle方法了。當然琅锻,調(diào)用恼蓬,應該也沒什么問題处硬。
    c. 進一步的,Android 3.0 以后桐腌,可以通過設置 BitmapFactory.Options.inBitmap 來復用原來的Bitmap內(nèi)存案站。當然蟆盐,什么時候可以復用,什么時候不能痹愚,這就是另一個話題了拯腮。比如萝喘,當圖片分辨率相同的情況下,在BitmapFactory的decode方法中启妹,應該是會復用的翅溺。
    并且吨拍,官方推薦用 Glide 或者 LruCache 來做圖片緩存管理羹饰。這個時候就可以參考 https://developer.android.google.cn/topic/performance/graphics/cache-bitmap.html 了队秩。

那么,現(xiàn)在還有人要兼容 Android 3.0 以前的版本嗎鸟蟹?我想是沒有了,所以已經(jīng)不需要主動調(diào)用recycle方法熊经。

不過悉盆,以上都是理論分析,主動調(diào)用recycle會不會比等待GC更有效一點呢脚翘?比如来农,主動降內(nèi)存。畢竟繁莹,當一個圖片列表中的Bitmap都很大的時候,會不會發(fā)生GC不及時的情況薄风?這就不知道了,等哪天寫個demo驗證一下吧撇他。
但是,如果開發(fā)過程中正好用到了這種情況僻弹,我覺得可以大膽的不去調(diào)用recycle芭毙,注意看一下內(nèi)存變化就行了。如果真的因此而不能通過測試侈百,大不了再把recycle加回來好了。特別是對大部分人來說例证,圖片列表里面的圖片分辨率也不會搞那么大的。

寫在最后的最后,上面貼的官方鏈接手趣,是看別人貼出來朝群,然后我一個一個跳轉(zhuǎn)過去的姜胖。如果直接進入Android開發(fā)者首頁蚜锨,我就不知道有什么方法能找到它們了。因為氛悬,不像API指南棍现,或者那一套Training,可以直接點擊菜單跳轉(zhuǎn)過去。這幾個鏈接坚洽,反正我是找不到從界面跳轉(zhuǎn)進去的入口鞍盗。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末敷存,一起剝皮案震驚了整個濱河市锚烦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖苞尝,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件曼氛,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機餐抢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來绞呈,“玉大人倘要,你說我怎么就攤上這事志鹃。” “怎么了埠胖?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵红柱,是天一觀的道長。 經(jīng)常有香客問我袍暴,道長蚂会,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任枫慷,我火速辦了婚禮或听,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘足丢。我一直安慰自己,他們只是感情好耀鸦,可當我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布洛姑。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天虹曙,我揣著相機與錄音恨狈,去河邊找鬼。 笑死,一個胖子當著我的面吹牛关面,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播捂齐,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蛮放,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起贵少,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體唆鸡,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片事镣。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖逗嫡,靈堂內(nèi)的尸體忽然破棺而出株依,到底是詐尸還是另有隱情驱证,我是刑警寧澤,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布恋腕,位于F島的核電站抹锄,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏荠藤。R本人自食惡果不足惜伙单,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望哈肖。 院中可真熱鬧吻育,春花似錦、人聲如沸淤井。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至缎除,卻和暖如春严就,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背器罐。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留渐行,地道東北人轰坊。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像祟印,于是被迫代替她去往敵國和親肴沫。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,619評論 2 354

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