Android 内存优化 第一章

第一章 内存优化

内存优化,这是android开发必经之路,那么怎样去优化呢?

首页先看看内存方面面临问题

  • (1)有限的堆内存,原始只有16M
  • (2)内存消耗和设备、操作系统、屏幕尺寸等因素有关系
  • (3)程序不能直接控制
  • (4)支持后台多任务
  • (5)运行在虚拟机上

内存泄漏和内存溢出区别

  • 内存溢出(out of memony):在想程序申请内存时,没有足够的内存使用,导致内存溢出,比如:一-个Integer变量,给他一个Long类型的数据,那肯定溢出了。
  • 内存泄漏(memony leak):程序申请内存后,没有释放,一直占有内存,一次内存泄漏可以忽略,但是内存时有限的,迟早会占满。

其中内存泄漏可以分为4类

  1. 常发性内存泄漏:经常申请内存还不释放内存,能明确查到的这类型泄漏
  2. 偶发性内存泄漏:偶然(在特定环境下)申请内存,造成内存泄漏
  3. 一次性内存泄漏:只有一个申请内存,造成内存泄漏
  4. 隐世行内存泄漏:程序运行过程中,不停分配内存,直到程序运行完成后,再释放。这类型泄漏危害比较大

内存泄漏造成的影响

  1. 程序变慢了,卡顿了,相应速度变慢了(内存占用过高,JVM会频繁gc)
  2. 莫名消失,在后台占用时间过长,会被杀死
  3. 直接奔了

第一步 查看内存使用情况

观察和计算系统内存使用情况,可以使用Android提供给我们的两个工具procstats,meminfo。他们一个侧重于后台的内存使用,另一个是运行时的内存使用

  • Procstats:可以去监视你app在一段时间的行为,包括在后台运行了多久,并在此段时间使用了多少内存。从而帮助你快速的找到应用中不效率和不规范的地方去避免影响其performs,尤其是在低内存的设备上运行时。
    • 通过adb shell命令去使用procstats(adb shell dumpsys procstats –hours 3)
  • meminfo:它是根据PSS标准 (Proportional Set Size——实际物理内存)计算每个进程的内存使用并且按照重要程度排序。

第二步 减少内存占用

(1)使用更加轻量的数据解决
  • 我们可以考虑使用ArrayMap/SparseArray而不是HashMap等传统数据结构
  • SparseArray可以避免AutoBox,查找方法为二分查找,效率比HashMap低一些
(2)避免在Android里面使用Enum

官方文档是这样说的,枚举相对于静态常量来说,需要两倍甚至更多的内存

(3)Bitmap

Bitmap是内存消耗大户,绝大多数的OOM崩溃都是在操作Bitmap时产生的,下面来看看几个处理图片的方法:

图片显示

根据需求显示图片,例如,显示缩略图图时用小图,当用户点击后,显示完整的大图。
图片大小

显示图片的时候,要对图片大小进行处理,不要直接用ImageView,来直接显示,可以使用BitmapFactory.Options设置缩放比例。
图片像素

Android中图片有四种属性,分别是:

  • ALPHA_8:每个像素占用1byte内存
  • ARGB_4444:每个像素占用2byte内存
  • ARGB_8888:每个像素占用4byte内存 (默认)
  • RGB_565:每个像素占用2byte内存

Android默认的颜色模式为ARGB_8888,这个颜色模式色彩最细腻,显示质量最高。但同样的,占用的内存也最大。 所以在对图片效果不是特别高的情况下使用RGB_565(565没有透明度属性)

publicstaticBitmapreadBitMap(Contextcontext, intresId) {  
    BitmapFactory.Optionsopt = newBitmapFactory.Options();  
    opt.inPreferredConfig = Bitmap.Config.RGB_565;  
    opt.inPurgeable = true;  
    opt.inInputShareable = true;  
    //获取资源图片   
    InputStreamis = context.getResources().openRawResource(resId);  
    returnBitmapFactory.decodeStream(is, null, opt);  
} 

图片回收

使用Bitmap过后,就需要及时的调用Bitmap.recycle()方法来释放Bitmap占用的内存空间,而不要等Android系统来进行释放。

// 先判断是否已经回收  
if(bitmap != null && !bitmap.isRecycled()){  
    // 回收并且置为null  
    bitmap.recycle();  
    bitmap = null;  
}  
System.gc();  

捕获异常

在压缩图片的过程中,如果图片是大图,则非常容易造成oom,所以这里要捕获异常,对压缩失败的图片进行处理

(4)对象引用类型

引用类型:强引用,软引用,弱引用,虚引用,(这里就不做解释)

利用四种引用能够解决一些问题,例如如果想避免OutOfMemory异常的发生,则可以使用软引用。

如果对于应用的性能更在意,想尽快回收一些占用内存比较大的对象,则可以使用弱引用。

还有就是可以根据对象是否经常使用来判断。

如果该对象可能会经常使用的,就尽量用软引用。如果该对象不被使用的可能性更大些,就可以用弱引用。

另外,和弱引用功能类似的是WeakHashMap。WeakHashMap对于一个给定的键,其映射的存在并不阻止垃圾回收器对该键的回收,回收以后,其条目从映射中有效地移除。WeakHashMap使用ReferenceQueue实现的这种机制。

(5)了解使用的类
  • 在用处理字符串时候,可以使用String.indexOf(),String.lastindexOf()等实现方法;
  • 在使用ArrayList时候,尽量初始化就写好大小,这样减少数组的重复移动;
  • 还有在使用for循环中,在尽量直接复制count,不要使用this.getCount等。
  • 尽量少的使用浮点数
  • 避免频繁调用的类中使用get和set方法,可以直接访问变量。
  • 尽量不要创建没必要的对象。
  • 对应的常量使用static final
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值