### Bitmap
#### 1、Bitmap使用需要注意哪些問題 ?
> * 參考回答:
> * **要選擇合適的圖片規格(bitmap類型)**:通常我們優化Bitmap時,當需要做性能優化或者防止OOM,我們通常會使用RGB\_565,因為ALPHA\_8只有透明度,顯示一般圖片沒有意義,Bitmap.Config.ARGB\_4444顯示圖片不清楚,Bitmap.Config.ARGB\_8888占用內存最多。:
> * ALPHA\_8 每個像素占用1byte內存
> * ARGB\_4444 每個像素占用2byte內存
> * ARGB\_8888 每個像素占用4byte內存(默認)
> * RGB\_565 每個像素占用2byte內存
> * **降低采樣率**:BitmapFactory.Options 參數inSampleSize的使用,先把options.inJustDecodeBounds設為true,只是去讀取圖片的大小,在拿到圖片的大小之后和要顯示的大小做比較通過calculateInSampleSize()函數計算inSampleSize的具體值,得到值之后。options.inJustDecodeBounds設為false讀圖片資源。
> * **復用內存**:即通過軟引用(內存不夠的時候才會回收掉),復用內存塊,不需要再重新給這個bitmap申請一塊新的內存,避免了一次內存的分配和回收,從而改善了運行效率。
> * **使用recycle()方法及時回收內存**。
> * **壓縮圖片**。
#### 2、Bitmap.recycle()會立即回收么?什么時候會回收?如果沒有地方使用這個Bitmap,為什么垃圾回收不會直接回收?
> * 參考回答:
> * 通過源碼可以了解到,加載Bitmap到內存里以后,是包含**兩部分內存區域**的。簡單的說,一部分是**Java部分**的,一部分是**C部分**的。這個Bitmap對象是由Java部分分配的,不用的時候系統就會自動回收了
> * 但是那個對應的**C可用**的內存區域,虛擬機是不能直接回收的,這個只能調用底層的功能釋放。所以需要調用recycle()方法來釋放C部分的內存
> * bitmap.recycle()方法用于回收該Bitmap所占用的內存,接著將bitmap置空,最后使用System.gc()調用一下系統的垃圾回收器進行回收,調用System.gc()并不能保證立即開始進行回收過程,而只是為了加快回收的到來。
#### 3、一張Bitmap所占內存以及內存占用的計算
> * 參考回答:
> * Bitamp 所占內存大小 = 寬度像素 x (inTargetDensity / inDensity) x 高度像素 x (inTargetDensity / inDensity)x 一個像素所占的內存字節大小
> * 注:這里inDensity表示目標圖片的dpi(放在哪個資源文件夾下),inTargetDensity表示目標屏幕的dpi,所以你可以發現inDensity和inTargetDensity會對Bitmap的寬高進行拉伸,進而改變Bitmap占用內存的大小。
> * 在Bitmap里有兩個獲取內存占用大小的方法。
> * **getByteCount()**:API12 加入,代表存儲 Bitmap 的像素需要的最少內存。
> * **getAllocationByteCount()**:API19 加入,代表在內存中為 Bitmap 分配的內存大小,代替了 getByteCount() 方法。
> * 在**不復用 Bitmap** 時,getByteCount() 和 getAllocationByteCount 返回的結果是一樣的。在通過**復用 Bitmap** 來解碼圖片時,那么 getByteCount() 表示新解碼圖片占用內存的大 小,getAllocationByteCount() 表示被復用 Bitmap 真實占用的內存大小
#### 4、Android中緩存更新策略 ?
> * 參考回答:
> * Android的緩存更新策略**沒有統一的標準**,一般來說,緩存策略主要包含**緩存的添加、獲取和刪除**這三類操作,但不管是內存緩存還是存儲設備緩存,它們的緩存容量是有限制的,因此刪除一些舊緩存并添加新緩存,如何定義緩存的新舊這就是一種策略,**不同的策略就對應著不同的緩存算法**
> * 比如可以簡單地根據文件的最后修改時間來定義緩存的新舊,當緩存滿時就將最后修改時間較早的緩存移除,這就是一種緩存算法,但不算很完美
#### 5、LRU的原理 ?
> * 參考回答:
> * 為減少流量消耗,可采用緩存策略。常用的緩存算法是LRU(Least Recently Used):當緩存滿時, 會優先淘汰那些近期最少使用的緩存對象。主要是兩種方式:
> * **LruCache(內存緩存)**:LruCache類是一個線程安全的泛型類:內部采用一個LinkedHashMap以強引用的方式存儲外界的緩存對象,并提供get和put方法來完成緩存的獲取和添加操作,當緩存滿時會移除較早使用的緩存對象,再添加新的緩存對象。
> * **DiskLruCache(磁盤緩存)**: 通過將緩存對象寫入文件系統從而實現緩存效果