Android內存溢出 (oom)實戰

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 //百度一下就好
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章