android内存优化思考与汇总

对应用检查并优化的思路可以从两个方向着手

1.确定频繁分配内存的代码路径。
DDMS下的Allocation Tracker。它可以显示出程序运行中频繁分配内存的部分,并准确定位到对应的代码。
2.减少频繁的内存分配。
减少频繁地创建对象或者不在这些地方创建对象是一个显而易见的方法。
也有一些比较隐秘的内存消耗点,下面就介绍一下for循环的内存消耗。

1.生成Bitmap:
    InputStream is =this.getResources().openRawResource(R.drawable.img);
     BitmapFactory.Options options=new BitmapFactory.Options();
     options.inJustDecodeBounds = false;
     options.inSampleSize = 10;   //width,hight设为原来的十分一
     Bitmap bm =BitmapFactory.decodeStream(is,null,options);//BitmapFactory.decodeStream方法,

创建出一个bitmap,再将其设为ImageView的 source,decodeStream最大的秘密在于其直接用JNI>>nativeDecodeAsset()来完成decode,无需再使用java层的createBitmap从而节省了java层的空间(避免了一些对象的创建)。如果在读取时加上图片的Config参数,可以更有效减少加载的内存,从而减少发生OOM发生的几率。

2.及时回收Bitmap
 if(!bm.isRecycle() ){
     bm.recycle()   //回收图片所占的内存
     system.gc()  //提醒系统及时回收
}
调用recycle(),会开启一个线程去处理,具体什么时候回收只有系统知道。(属于建议 JVM 进行垃圾回收)

这个就是为什么我们有的地方调用了它,那个地方还是会报oom的原因。
但是有总归比没有好,它可以有效减少oom的概率。

回收缓存资源
(1)//用来存放图片的缓存

 HashMap<Integer, Bitmap>bitmapCache = new HashMap<Integer, Bitmap>();
  //如果没有图片,或者不存在
   if(bitmapCache.isEmpty() || !AppConst.bitmapCache.containsKey(position)){
                bitmapCache.put(position,bm);
            }

(2)定义FreeBitmap函数,在activity结束的时候,调用FreeBitmap函数,回收map中的资源

 private void FreeBitmap(HashMap<Integer, Bitmap> cache){
        if(cache.isEmpty()){
            return;
        }
        for(Bitmap bitmap:cache.values()){
            if(bitmap != null && !bitmap.isRecycled()){
                bitmap.recycle();
            }
        }
        cache.clear();
    }
3.手动干预堆内存:

(1)增强程序堆内存的处理效率:
开发一些大型游戏或耗资源的应用时可考虑手动干涉GC处理,如程序onCreate时调用VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
(2)强行设置APP最小内存大小:
VMRuntime.getRuntime().setMinimumHeapSize(6* 1024* 1024); //设置最小heap内存为6MB大小

4.修改Android手机的dalvik-heap的大小

工作中遇到了一个需要debug的应用,需要去try修改dalvik.vm.heapgrowthlimit来check这个问题。所以,这里记录下,修改的方法:
1. dalvik.vm.heapgrowthlimit的设置在 /system/build.prop中
2. adb remount / adb pull /system/build.prop
3. 修改build.prop文件,将dalvik.vm.heapgrowthlimit修改后,adb pull /system/
4. chmod修改build.prop的权限。这里要注意,我开始修改的是chmod 777,后来系统起不来。ll 查看system/下文件权限,发现时744。同理: chmod 744,发现就 OK了。原来权限给高了还不行。

5.使用实体类比接口好

假设你有一个HashMap对象,你可以将它声明为HashMap或者Map:
Map map1 = new HashMap();
HashMap map2 = new HashMap();
哪个更好呢?
按照传统的观点Map会更好些,因为这样你可以改变他的具体实现类,只要这个类继承自Map接口。传统的观点对于传统的程序是正确的,但是它并不适合嵌入式系统。调用一个接口的引用会比调用实体类的引用多花费一倍的时间。如果HashMap完全适合你的程序,那么使用Map就没有什么价值。如果有些地方你不能确定,先避免使用Map,剩下的交给IDE提供的重构功能好了。(当然公共API是一个例外:一个好的API常常会牺牲一些性能)

6.避免使用枚举

枚举变量非常方便,但不幸的是它会牺牲执行的速度和并大幅增加文件体积。例如:

public class Foo {
           public enum Shrubbery { GROUND, CRAWLING, HANGING }
    }

会产生一个900字节的.class文件(Foo Shubbery.class) VALUES”的静态数组变量中。而这么一大堆代码,仅仅是为了使用三个 整数。
这样:Shrubbery shrub =Shrubbery.GROUND;会引起一个对静态变量的引用,如果这个静态变量是final int,那么编译器会直接内联这个常数。一方面说,使用枚举变量可以让你的API更出色,并能提供编译时的检查。所以在通常的时候你毫无疑问应该为公共API选择枚举变量。但是当性能方面有所限制的时候,你就应该避免这种做法了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值