Android中圖片佔用內存的計算

在Android開發中,我現在發現很多人還不會對圖片佔用內存進行很好的計算。因此撰寫該博文來做介紹,期望達到拋磚引玉的作用。

  Android中一張圖片(BitMap)佔用的內存主要和以下幾個因數有關:圖片長度,圖片寬度,單位像素佔用的字節數。
一張圖片(BitMap)佔用的內存=圖片長度*圖片寬度*單位像素佔用的字節數
圖片長度和圖片寬度的單位是像素。
圖片(BitMap)佔用的內存應該和屏幕密度(Density)無關,雖然我暫時還拿不出直接證據。
   創建一個BitMap時,其單位像素佔用的字節數由其參數BitmapFactory.OptionsinPreferredConfig變量決定。
inPreferredConfig爲Bitmap.Config類型,
Bitmap.Config是個枚舉類型,它可以爲以下值
Enum Values
Bitmap.Config  ALPHA_8  Each pixel is stored as a single translucency (alpha) channel. 
This is very useful to efficiently store masks for instance. No color information is stored. With this configuration, each pixel requires 1 byte of memory.
此時圖片只有alpha值,沒有RGB值,一個像素佔用一個字節
Bitmap.Config  ARGB_4444  This field is deprecated. Because of the poor quality of this configuration, it is advised to use ARGB_8888instead.  
這種格式的圖片,看起來質量太差,已經不推薦使用。
Each pixel is stored on 2 bytes. The three RGB color channels and the alpha channel (translucency) are stored with a 4 bits precision (16 possible values.) This configuration is mostly useful if the application needs to store translucency information but also needs to save memory. It is recommended to use ARGB_8888 instead of this configuration.
一個像素佔用2個字節,alpha(A)值,Red(R)值,Green(G)值,Blue(B)值各佔4個bites,共16bites,即2個字節
Bitmap.Config  ARGB_8888  Each pixel is stored on 4 bytes. Each channel (RGB and alpha for translucency) is stored with 8 bits of precision (256 possible values.) This configuration is very flexible and offers the best quality. It should be used whenever possible
一個像素佔用4個字節,alpha(A)值,Red(R)值,Green(G)值,Blue(B)值各佔8個bites,共32bites,即4個字節
這是一種高質量的圖片格式,電腦上普通採用的格式。它也是Android手機上一個BitMap的
默認格式。
Bitmap.Config  RGB_565  Each pixel is stored on 2 bytes and only the RGB channels are encoded: red is stored with 5 bits of precision (32 possible values), green is stored with 6 bits of precision (64 possible values) and blue is stored with 5 bits of precision. This configuration can produce slight visual artifacts depending on the configuration of the source. For instance, without dithering, the result might show a greenish tint. To get better results dithering should be applied. This configuration may be useful when using opaque bitmaps that do not require high color fidelity.
一個像素佔用2個字節,沒有alpha(A)值,即不支持透明和半透明,Red(R)值佔5個bites ,Green(G)值佔6個bites  ,Blue(B)值佔5個bites,共16bites,即2個字節.對於沒有透明和半透明顏色的圖片來說,該格式的圖片能夠達到比較的呈現效果,相對於ARGB_8888來說也能減少一半的內存開銷。因此它是一個不錯的選擇。另外我們通過android.content.res.Resources來取得一個張圖片時,它也是以該格式來構建BitMap的.
Android4.0開始,該選項無效。即使設置爲該值,系統任然會採用 ARGB_8888來構造圖片
:ARGB指的是一種色彩模式,裏面A代表Alpha,R表示redG表示greenB表示blue,其實所有的可見色都是紅綠藍組成的,所以紅綠藍又稱爲三原色。
A  R  G  B
透明度 紅色 綠色 藍色
簡單點說

 圖片格式(Bitmap.Config

 佔用內存的計算方向

 一張100*100的圖片佔用內存的大小

 ALPHA_8

 圖片長度*圖片寬度

 100*100=10000字節

 ARGB_4444

 圖片長度*圖片寬度*2

 100*100*2=20000字節

 ARGB_8888

 圖片長度*圖片寬度*4

 100*100*4=40000字節

 RGB_565 

 圖片長度*圖片寬度*2

 100*100*2=20000字節


另外,需要注意這裏的圖片佔用內存是指在Navtive中佔用的內存,當然BitMap使用的絕大多數內存就是該內存。
因爲我們可以簡單的認爲它就是BitMap所佔用的內存。
  Bitmap對象在不使用時,我們應該先調用recycle(),然後才它設置爲null.
雖然Bitmap在被回收時可以通過BitmapFinalizer來回收內存。但是調用recycle()是一個良好的習慣
在Android4.0之前,Bitmap的內存是分配在Native堆中,調用recycle()可以立即釋放Native內存。
從Android4.0開始,Bitmap的內存就是分配在dalvik堆中,即JAVA堆中的,調用recycle()並不能立即釋放Native內存。但是調用recycle()也是一個良好的習慣。
通過dumpsys meminfo命令可以查看一個進程的內存使用情況,
當然也可以通過它來觀察我們創建或銷燬一張BitMap圖片內存的變化,從而推斷出圖片佔用內存的大小。
示例adb shell "dumpsys meminfo com.lenovo.robin"
運行結果。
Applications Memory Usage (kB):
Uptime: 18696550 Realtime: 18696541
** MEMINFO in pid 7985 [com.lenovo.robin] **
                    native   dalvik    other    total
            size:     4828     5379      N/A    10207
       allocated:     4073     2852      N/A     6925
            free:       10     2527      N/A     2537
           (Pss):      608      317     1603     2528
  (shared dirty):     2240     1896     6056    10192
    (priv dirty):      548       36     1276     1860

 Objects
           Views:        0        ViewRoots:        0
     AppContexts:        0       Activities:        0
          Assets:        2    AssetManagers:        2
   Local Binders:        5    Proxy Binders:       11
Death Recipients:        1
 OpenSSL Sockets:        0

 SQL

               heap:        0         MEMORY_USED:        0
 PAGECACHE_OVERFLOW:        0         MALLOC_SIZE:        0
關於內存統計的更多內容請參考《Android中如何查看內存
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章