Android内存优化方法

青云开 · · 192 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

一. 避免OOM :

1.使用更加轻量的数据结构:例如,我们可以考虑使用ArrayMap/SparseArray而不是HashMap等传统数据结构(数组 加链表实现 扩容x2)  ,SparseArray更加高效,在于他们避免了对key与value的自动装箱. 使用 StringBuilder 或StringBuffer 代替 String 对字符串进行操作;

2. 减少Bitmap 对象的内存占用;inSampleSize:缩放比例,在把图片载入内存之前,我们需  要先计算出一个合适的缩放比例,避免不必要的大图载入。decode format 设置编码,:inPurgeable:设置为True时,表示系统内存不足时可以被回 收,设置为False时,表示不能被回收

3. xhdpi 对应文件下放置对应的图片,并且使用更小的图片;资源文件需要选择合适的文件夹进行存放

4. 内存对象的重复利用;减少对象的创建或者采用创建对象池,处理好复用逻辑, 对常用的对象采用单例模式创建 降低内存的分配;    ListView Gridview 的ConvertView 的复用;Bitmap 的复用,LRU的机制来缓存处理好的Bitmap 并对bitmap 进行压缩;

二.避免对象的内存泄漏(反复进入某个界面 内存并没有消失)

内存对象的泄漏,会导致一些不再使用的对象无法及时释放,这样一方面占用了宝贵的内存空间,很容易导致后续需要分配内存的时候,空闲空间不足而出现OOM。

1.ActivityContext  被传递到其他实例中 导致自身被引用而发生了泄漏,非静态内部类持有外部的引用,导致内存泄漏;Handler  导致Activity泄漏(如果Handler中有延迟的任务或者是等待执行的任务队列过长,都有可能因为Handler继续执行而导致Activity发生泄漏。)为了解决这个问题,可以在UI退出之前,执行remove Handler消息队列中的消息与runnable对象。或者是使用Static + WeakReference的方式来达到断开Handler与Activity之间存在引用关系的目的。Application Context而不是Activity Context对于非UI 的Context 可以使用 Application Context。 开启Activity ,广播,Service,获取资源等操作单例的持有Context 换为持有Application Context

2.打开资源的关闭 ,如数据库Cursor对象,文件流, Dialog  要关闭 ,广播要解除注册;等

3. 临时创建的Bitmap的回收 ,退出显示图片的页面时,清空缓存释放内存;

4 软引用与弱引用的应用

如果一个对象只具有软引用,那么如果内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。

弱引用与软引用的根本区别在于:只具有弱引用的对象拥有更短暂的生命周期,可能随时被回收。而只具有软引用的对象只有当内存不够的时候才被回收,在内存足够的时候,通常不被回收。

假设我们的应用会用到大量的默认图片,比如应用中有默认的头像,默认游戏图标等等,这些图片很多地方会用到。如果每次都去读取图片,由于读取文件需要硬件操作,速度较慢,会导致性能较低。所以我们考虑将图片缓存起来,需要的时候直接从内存中读取。但是,由于图片占用内存空间比较大,缓存很多图片需要很多的内存,就可能比较容易发生OutOfMemory异常。这时,我们可以考虑使用软引用技术来避免这个问题发生。

首先定义一个HashMap,保存软引用对象。

```java

private Map> imageCache = new HashMap>();

private Map> imageCache = new HashMap>();

public void addBitmapToCache(String path) {

// 强引用的Bitmap对象

Bitmap bitmap = BitmapFactory.decodeFile(path);

// 软引用的Bitmap对象

SoftReference softBitmap = new SoftReference(bitmap);

// 添加该对象到Map中使其缓存

imageCache.put(path, softBitmap);

}

public Bitmap getBitmapByPath(String path) {

// 从缓存中取软引用的Bitmap对象

SoftReference softBitmap = imageCache.get(path);

// 判断是否存在软引用

if (softBitmap == null) {

return null;

}

// 取出Bitmap对象,如果由于内存不足Bitmap被回收,将取得空

Bitmap bitmap = softBitmap.get();

return bitmap;

}

```


使用软引用以后,在OutOfMemory异常发生之前,这些缓存的图片资源的内存空间可以被释放掉的,从而避免内存达到上限,避免Crash发生。

需要注意的是,在垃圾回收器对这个Java对象回收前,SoftReference类所提供的get方法会返回Java对象的强引用,一旦垃圾线程回收该Java对象之后,get方法将返回null。所以在获取软引用对象的代码中,一定要判断是否为null,以免出现NullPointerException异常导致应用崩溃。

个人认为,如果只是想避免OutOfMemory异常的发生,则可以使用软引用。如果对于应用的性能更在意,想尽快回收一些占用内存比较大的对象,则可以使用弱引用。还有就是可以根据对象是否经常使用来判断。如果该对象可能会经常使用的,就尽量用软引用。如果该对象不被使用的可能性更大些,就可以用弱引用。

本文来自:开源中国博客

感谢作者:青云开

查看原文:Android内存优化方法

192 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet