Bitmap的產生和釋放流程

來源:互聯網
上載者:User
BitmapFactory.decodeResource和BitmapFactory.decodeStream,相信對於有過android app開發經驗的人來說都是很熟悉了。關於Bitmap的OOM問題,網上也有很多文章進行了分析,不少文章都說為避免OOM,最好使用BitmapFactory.decodeStream,但是具體說明原因的我至今沒有找到,所以趁著10.1期間有空,就調查了一番,希望結果對大家能有協助。

      先來張時序圖,看了這張圖,估計很多問題都不用說明了:


 

下面做些說明:

1,函數externalBytesAvailable(...)的記憶體計算方法詳細請參見文章《Android Bitmap記憶體限制》;

2,Bitmap.createScaledBitmap時可能會對Bitmap進行縮放,縮放所使用的Options請參見下面這段代碼:

 

[java] view plaincopy

  1. public static Bitmap decodeResourceStream(Resources res, TypedValue value,  
  2.         InputStream is, Rect pad, Options opts) {  
  3.   
  4.     if (opts == null) {  
  5.         opts = new Options();  
  6.     }  
  7.   
  8.     if (opts.inDensity == 0 && value != null) {  
  9.         final int density = value.density;  
  10.         if (density == TypedValue.DENSITY_DEFAULT) {  
  11.             opts.inDensity = DisplayMetrics.DENSITY_DEFAULT;  
  12.         } else if (density != TypedValue.DENSITY_NONE) {  
  13.             opts.inDensity = density;  
  14.         }  
  15.     }  
  16.       
  17.     if (opts.inTargetDensity == 0 && res != null) {  
  18.         opts.inTargetDensity = res.getDisplayMetrics().densityDpi;  
  19.     }  
  20.       
  21.     return decodeStream(is, pad, opts);  
  22. }  

當放大時,會加大造成OOM的可能性;
3,BitmapFactory.decodeResource比起BitmapFactory.decodeStream來說,在沒有參數Options opts的情況下,確實是多佔用了記憶體,因為多了BitmapFactory.finishDecode這一步,這裡多了一個Bitmap.createScaledBitmap操作;

 

4,關於使用BitmapFactory.decodeResource和BitmapFactory.decodeStream的效率對比,大家可以參見文章《Android 記憶體最佳化測試》

5,關於文章《Android 記憶體最佳化測試》提到的使用BitmapDrawable是最節省記憶體的方法,原因是frameworks\base\core\java\android\content\res\Resources.java對Bitmap做了緩衝處理,文中所有的array其實都是指向同一個Bitmap,這一點也可以通過Bitmap.toString的輸出資訊來證明。

備忘:時序圖看不清楚的,可以到http://download.csdn.net/detail/imyfriend/4617329下載原圖。 

 

  

上篇文章談到了Bitmap的產生,現在說說Bitmap的釋放,要不總是有種沒說完的感覺。

      Bitmap的釋放相對來說,比較簡單,還是先上張時序圖吧!

 

一些說明:
1,AndroidPixelRef的設定是在Bitmap產生的GraphicsJNI::setJavaPixelRef裡完成的,這裡可以參見文章《Bitmap的產生流程之BitmapFactory.decodeResource VS BitmapFactory.decodeStream》。具體代碼如下:

[cpp] view plaincopy

  1. bool GraphicsJNI::setJavaPixelRef(JNIEnv* env, SkBitmap* bitmap,  
  2.                                   SkColorTable* ctable, bool reportSizeToVM) {  
  3. ......  
  4.     SkPixelRef* pr = reportSizeToVM ?  
  5.                         new AndroidPixelRef(env, addr, size, ctable) :  
  6.                         new SkMallocPixelRef(addr, size, ctable);  
  7.   
  8.   
  9. ......  
  10. }  

2,VMRuntime.trackExternalFree把Bitmap佔用的虛擬機器heap記憶體歸還。如果你有興趣的話,請具體參見dalvik\vm\native\dalvik_system_VMRuntime.c。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.