Android內存溢出 (oom)實戰
作者今日備受oom煎熬,最後眼睛都盯出花來了才搞定。痛定思痛,決定寫一片文章來幫助後人,順便吊念一下苦逼的過去。
檢查篇:
遇到oom一定不能慌,決不能一出來oom就上網查然後一通亂改。相反你要冷靜下來看看是誰惹的禍!
不冤枉好人
oom異常有這樣的特性:
- 報錯的地方不一定是元兇
- 有至少一個地方消耗了大量內存
消耗的內存沒有回收
第一點需要特殊解釋下:
比如說Android給了你50M內存,當“元兇A”消耗49M內存後不動了,其他操作(B)又消耗了1.1M內存,Android這時候就會在B那報oom的錯,說沒有資源了。於是B就成了替罪羊。
找出元兇
這是一個痛苦的過程,但爲了過大的讀者的身心健康,我必須找到一個方便的方法。這面這句放在Application中,可以監控你應用的內存變化。接着一個個去試吧(-.-)。
new Thread(new Runnable() {
@Override
public void run() {
while(true){
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Logs.d(TAG,"最大可用內存:"+Runtime.getRuntime().maxMemory()/1024/1024+"m");
Logs.d(TAG,"已獲取內存:"+Runtime.getRuntime().totalMemory()/1024/1024+"m");
Logs.d(TAG,"已獲取內存的未使用內存:"+Runtime.getRuntime().freeMemory()/1024/1024+"m");
}
}
}).start();
已知元兇
- activity中引用了超過本身生命週期的對象
- 引入的圖片過大或者過多,亦或兩者兼有
- gifview的jar包(作者就是這個)
解決辦法:
- activity中引用了超過本身生命週期的對象
去掉引用:
變量A.close(); //不同的對象,方法不一樣。比如:clear,finish一下
變量A=null; //保險起見(有些對象必須。。) 引入的圖片過大或者過多,亦或兩者兼有
可嘗試用矩陣縮放圖片/** * 獲得縮略圖 * @param index * @param zoom * @return */ private Bitmap getDrawable(int index, int zoom) { if (index >= 0 && index < imagePathes.size()) { String path = imagePathes.get(index); BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; int mWidth = options.outWidth; int mHeight = options.outHeight; int s = 1; while ((mWidth / s > itemw * 2 * zoom) || (mHeight / s > itemh * 2 * zoom)) { s *= 2; Logs.d(TAG ,"------->s="+s); } options = new BitmapFactory.Options(); options.inSampleSize = s; options.inPreferredConfig = Config.ARGB_8888; Bitmap bm = decodeFile(path, options); if (bm != null) { int h = bm.getHeight(); Logs.d(TAG, "------->h="+h); int w = bm.getWidth(); Logs.d(TAG,"------->w="+w); float ft = (float) ((float) w / (float) h); float fs = (float) ((float) itemw / (float) itemh); int neww = ft >= fs ? itemw * zoom : (int) (itemh * zoom * ft); int newh = ft >= fs ? (int) (itemw * zoom / ft) : itemh * zoom; float scaleWidth = ((float) neww) / w; float scaleHeight = ((float) newh) / h; Matrix matrix = new Matrix(); matrix.postScale(scaleWidth, scaleHeight); bm = Bitmap.createBitmap(bm, 0, 0, w, h, matrix, true); return bm; } } return null; }
- gifview的jar包(作者就是這個)
換個顯示gif的jar包吧。
android-gif-drawable-master //百度一下就好