zoukankan      html  css  js  c++  java
  • android 内存溢出oom错误的一些小见解

    转:http://blog.csdn.net/xuhui_7810/article/details/9493681

    我们在代码里调用setBackgroundResource(int resid)来设置一个view控件的背景时,如果图片过大,或者调用setBackgroundResource(int resid)多次时,有可能导致内存溢出.查看代码:

        public void setBackgroundResource(int resid) {
            if (resid != 0 && resid == mBackgroundResource) {
                return;
            }


            Drawable d= null;
            if (resid != 0) {
                d = mResources.getDrawable(resid);
            }
            setBackgroundDrawable(d);


            mBackgroundResource = resid;
        }

    可以发现,背景图片最后设置为了一个Drawable对象.Drawable对象占用的内存分为java层的和底层的两部份.JAVA层的内存,如果在你的view释放时,你的背景图片调用了Drawable的setCallback(null), 即取消你的背景图片在VM里的引用,则JAVA这部份的内存空间,在系统调用GC函数时可以把它回收. 但是在native层的内存,GC是释放不了的.这样就会导致有内存泄漏. 解决这个问题的办法有很多种,下面我来说说最简单的一种:

            设置背景时,不要调用setBackgroundResource(int resid),而改用setBackgroundDrawable(Drawable d) 这个函数,这个函数的参数d 用一个BitmapDrawable new出来.上代码:

    [java] view plaincopy
     
    1. Bitmap mBgBitmap = null;  
    2.         mBgBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.unlock_bg);  
    3.         setBackgroundDrawable(new BitmapDrawable(mBgBitmap));  

    这样的好处就是,我们可以保留图片的Bitmap引用mBgBitmap,在我们的VIEW释放时,我们显示的调用

    [java] view plaincopy
     
    1. if(mBgBitmap != null  && !mBgBitmap.isRecycled())  
    2.         {  
    3.             mBgBitmap.recycle();  
    4.             mBgBitmap = null;  
    5.         }     


    这段代码,就可以把native层的内层也给释放掉,这样就可以彻底解决内存泄漏的问题

    加上LruCache效果相比更佳

    private LruCache mMemoryCache;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        // Get memory class of this device, exceeding this amount will throw an
        // OutOfMemory exception.
        final int memClass = ((ActivityManager) context.getSystemService(
                Context.ACTIVITY_SERVICE)).getMemoryClass();
    
        // Use 1/8th of the available memory for this memory cache.
        final int cacheSize = 1024 * 1024 * memClass / 8;
    
        mMemoryCache = new LruCache(cacheSize) {
            @Override
            protected int sizeOf(String key, Bitmap bitmap) {
                // The cache size will be measured in bytes rather than number of items.
                return bitmap.getByteCount();
            }
        };
        ...
    }
    
    public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
        if (getBitmapFromMemCache(key) == null) {
            mMemoryCache.put(key, bitmap);
        }
    }
    
    public Bitmap getBitmapFromMemCache(String key) {
        return mMemoryCache.get(key);
    }
    

      

  • 相关阅读:
    python note 30 断点续传
    python note 29 线程创建
    python note 28 socketserver
    python note 27 粘包
    python note 26 socket
    python note 25 约束
    Sed 用法
    python note 24 反射
    python note 23 组合
    python note 22 面向对象成员
  • 原文地址:https://www.cnblogs.com/lee0oo0/p/3290512.html
Copyright © 2011-2022 走看看