最近做新聞客戶端的時候在加載ListView的大圖時會發生內存溢出的問題。內存溢出(OOM)。為了便于理解,我們不妨打個比方。緩沖區溢出好比是將十磅的糖放進一個只能裝五磅的容器里。一旦該容器放滿了,余下的部分就溢出在柜臺和地板上,弄得一團糟。由于計算機程序的編寫者寫了一些編碼,但是這些編碼沒有對目的區域或緩沖區——五磅的容器——做適當的檢查,看它們是否夠大,能否完全裝入新的內容——十磅的糖,結果可能造成緩沖區溢出的產生。如果打算被放進新地方的數據不適合,溢得到處都是,該數據也會制造很多麻煩。但是,如果緩沖區僅僅溢出,這只是一個問題。到此時為止,它還沒有破壞性。當糖溢出時,柜臺被蓋住。可以把糖擦掉或用吸塵器吸走,還柜臺本來面貌。與之相對的是,當緩沖區溢出時,過剩的信息覆蓋的是計算機內存中以前的內容。除非這些被覆蓋的內容被保存或能夠恢復,否則就會永遠丟失。
首先想到的是三級緩存,從服務器下載下來的圖片經過網絡緩存,但是這種方法不優先加載, 速度慢,浪費流量。然后是本地緩存,次優先加載, 速度快;最后最好的是內存緩存,優先加載, 速度最快。我們都知道Android默認給每個app只分配16M的內存,所以用軟引用 SoftReference ? 在內存不夠時,垃圾回收器會考慮回收。但是在安卓2.3+,系統會優先將SoftReference的對象提前回收掉, 即使內存夠用。所以谷歌官方建議用LruCache。least recentlly use 最少最近使用算法
會將內存控制在一定的大小內, 超出最大值時會自動回收, 這個最大值開發者自己定。其實LruCache就是用了很多的HashMap,三百多行的代碼。
~~~
/**
* 內存緩存
*/
public class MemoryCacheUtils {
// private HashMap<String, SoftReference<Bitmap>> mMemoryCache = new
// HashMap<String, SoftReference<Bitmap>>();
private LruCache<String, Bitmap> mMemoryCache;
public MemoryCacheUtils() {
long maxMemory = Runtime.getRuntime().maxMemory() / 8;// 模擬器默認是16M
mMemoryCache = new LruCache<String, Bitmap>((int) maxMemory) {
@Override
protected int sizeOf(String key, Bitmap value) {
int byteCount = value.getRowBytes() * value.getHeight();// 獲取圖片占用內存大小
return byteCount;
}
};
}
/**
* 從內存讀
*
* @param url
*/
public Bitmap getBitmapFromMemory(String url) {
// SoftReference<Bitmap> softReference = mMemoryCache.get(url);
// if (softReference != null) {
// Bitmap bitmap = softReference.get();
// return bitmap;
// }
return mMemoryCache.get(url);
}
/**
* 寫內存
*
* @param url
* @param bitmap
*/
public void setBitmapToMemory(String url, Bitmap bitmap) {
// SoftReference<Bitmap> softReference = new
// SoftReference<Bitmap>(bitmap);
// mMemoryCache.put(url, softReference);
mMemoryCache.put(url, bitmap);
}
}
~~~
~~~
java中的引用
- 強引用 垃圾回收器不會回收, java默認引用都是強引用
- 軟引用 SoftReference ? 在內存不夠時,垃圾回收器會考慮回收
- 弱引用 WeakReference ?在內存不夠時,垃圾回收器會優先回收
- 虛引用 PhantomReference ?在內存不夠時,垃圾回收器最優先回收
~~~
~~~
</pre><pre name="code" class="java">為進一步優化,我們還可以考慮圖片壓縮技術:
~~~
~~~
//圖片壓縮處理
BitmapFactory.Options option = new BitmapFactory.Options();
option.inSampleSize = 2;//寬高都壓縮為原來的二分之一, 此參數需要根據圖片要展示的大小來確定
option.inPreferredConfig = Bitmap.Config.RGB_565;//設置圖片格式
~~~
當然,如果我們用BitmapUtils也是可以的。
- 前言
- 內存溢出的解決方案
- 安卓消息推送解決方案
- 語言識別和聊天機器人的實現
- 抽屜效果的實現(DrawerLayout和SlidingMenu的對比)
- 植物大戰僵尸經典開發步驟
- 屏幕適配全攻略
- 安卓圖像處理入門教程
- android開發常用工具箱
- java基礎知識總結
- 剖析軟件外包項目
- java基礎知識——網絡編程、IO流
- 安卓性能優化手冊
- 電商活動中刮刮卡的實現
- Android系統的安全設計與架構
- AsnycTask的內部的實現機制
- Android應用UI設計流程
- 數據結構與算法,每日一道
- html5全解析
- 深入解讀XML解析
- 新聞客戶端案例開發
- 細說Http協議
- win10+ubuntu雙系統安裝方案
- 隨機驗證碼實現案例
- 動態數組的實現案例
- 猜拳游戲案例
- 商業級項目——基金客戶端的架構設計與開發(上)