• android Menory 小结


    1. 不建议在Activity中使用static 变量,考虑使用Application。当然,static final例外

    Application也不要cache某个Activity使用的View,如果cache也一定要在这个Activity Destroy()时手动清空Application中对viewcache

    1. 线程造成内存泄露。

    public class MyActivity extends Activity {  

        @Override  

        public void onCreate(Bundle savedInstanceState) {  

            super.onCreate(savedInstanceState);  

            setContentView(R.layout.main);  

            new MyThread().start();  

        }  

      

        private class MyThread extends Thread{  

            @Override  

            public void run() {  

                super.run();  

                //do somthing  

            }  

        }  

    }

    假设MyThreadrun函数是一个很费时的操作,当我们开启该线程后,将设备的横屏变为了竖屏,一般情况下当屏幕转换时会重新创建Activity,按照我们的想法,老的Activity应该会被销毁才对,然而事实上并非如此。

     

    由于我们的线程是Activity的内部类,所以MyThread中保存了Activity的一个引用,当MyThreadrun函数没有结束时,MyThread是不会被销毁的,因此它所引用的老的Activity也不会被销毁,因此就出现了内存泄露的问题

     

    3BitmapDrawable

     

    BitmapDrawable的比较

     

    对比项

    Bitmap

    Drawable

    显示清晰度

    相同

    相同

    占用内存

    支持缩放

    支持色相色差调整

    支持旋转

    支持透明色

    绘制速度

    支持像素操作

    Drawable在内存占用和绘制速度这两个非常关键的点上胜过BitmapGoogle Android开发示例中提到绘制Bitmap的速度要快于Drawable,但经过实际测试后发现恰恰相反)。
    Bitmap相对于Drawable来说又可以调整色差色相以及直接对图片的各相素进行操作。

    1. 位图Bitmap占用内存

    比如一个320*480的图,

    320*480*Config+1kimage info

      android.graphics.Bitmap.Config=  ARGB_8888(32bit) 

      ARGB_4444(16bit)   

      RGB_565(16bit)

    /** 

     

      * 以最省内存的方式读取本地资源的图片 

     

      * @param context 

     

      * @param resId 

     

      * @return 

     

      */   

     

    public static Bitmap readBitMap(Context context, int resId){   

     

          BitmapFactory.Options opt = new BitmapFactory.Options();   

    //按每像素2字节读取 ,默认argb_88884字节

          opt.inPreferredConfig = Bitmap.Config.RGB_565;   

    //读取图片时内存不足自动回收本bitmap

          opt.inPurgeable = true;   

    //应该是共享流,以便因内存不足回收后,再次调用可以后台自动读取

          opt.inInputShareable = true;   

     

          //获取资源图片   

     

          InputStream is = context.getResources().openRawResource(resId);   

     

          return BitmapFactory.decodeStream(is,null,opt);   

     

    }

     

    5.

    异常捕获,避免程序崩溃

     

    try{

     

         Bitmap bmp=BitmapFactory.decodeFile(path,options);

     

    }catch (OutOfMemoryError e) {

     

         // 提示系统,进行内存回收

     

         System.gc();

     

        //清除程序缓存

     

         clearCache();

            

     

    }

     

     

     

    1. VMRuntime.getRuntime().setMinimumHeapSize(NewSize);

     

     堆(HEAP)是VM中占用内存最多的部分,通常是动态分配的。堆的大小不是一成不变的,通常有一个分配机制来控制它的大小。比如初始的HEAP4M大,当4M的空间被占用超过75%的时候,重新分配堆为8M大;当8M被占用超过75%,分配堆为16M大。倒过来,当16M的堆利用不足30%的时候,缩减它的大小为8M大。重新设置堆的大小,尤其是压缩,一般会涉及到内存的拷贝,所以变更堆的大小对效率有不良影响。

     

     上面只是个例子,不过可以看到三个参数:max heap size, min heap size, heap utilization(堆利用率)。

     

     Max Heap Size,是堆内存的上限值,Android的缺省值是16M(某些机型是24M),对于普通应用这是不能改的。函数setMinimumHeapSize其实只是改变了堆的下限值,它可以防止过于频繁的堆内存分配,当设置最小堆内存大小超过上限值时仍然采用堆的上限值,对于内存不足没什么作用。

     

     setTargetHeapUtilization(float newTarget) 可以设定内存利用率的百分比,当实际的利用率偏离这个百分比的时候,虚拟机会在GC的时候调整堆内存大小,让实际占用率向个百分比靠拢。

     

    rivate final static floatTARGET_HEAP_UTILIZATION = 0.75f; 在程序onCreate时就可以调用 VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION); 即可。

     

    6. 内部类的对象作用域超出Activity的范围:比如定义了一个内部类来存储数据,又把这个内部类的对象传给了其它Activity 或者Service等。因为内部类的对象会持有当前类的引用,所以也就持有了Context的引用。解决方法是把内部类抽取出来变成一个单独的类,或者把避免内部对象作用域超出Activity的作用域

  • 相关阅读:
    做足以让自己骄傲的活
    Count(*) 与 count(field) 一样吗?
    Explain Plan试分析
    Oracle SQL Developer中查看解释计划Explain Plan的两种方法
    整理+学习《骆昊-Java面试题全集(上)》
    【转】Java就业指导
    如何清晰的、高质量的给面试官介绍自己的电商项目【借鉴】
    留存的图片
    Linux学习_006_JavaEE程序员常用linux命令整理
    给Linux初学者的七个建议,值得一读
  • 原文地址:https://www.cnblogs.com/royi123/p/4273123.html
Copyright © 2020-2023  润新知