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 //百度一下就好
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值