所有Android的开发者一定都遇到过内存溢出这个头疼的问题,一旦出现这个问题,很难直接确定我们的应用是那里出了问题,要想定位问题的原因,必须通过一些内存分析工具和强大的经验积累才能快速的定位到问题具体出现在那里。

  基于移动开发具有的这个特性,本着尽量减少内存消耗的原则,以及我最近遇到的内存堆积(偶尔溢出)问题,总结一下这次解决这个问题的经验。

  问题源头:开始App功能没那么多的时候,是没有注意到这个问题的,后来功能越强越多,图片也越来越多的时候,用ADT自带的 Allocation Tracker查看了一下内存分配,明显有许多无用的data object,而没有释放掉,开始以为是universalImageLoader的问题,以为这个开源工程对图片的加载有问题,后来把图片全去掉再看内 存分配时还是有无用的data object,花了两天时间后发现是,是自己本地的一些bitmap没有回收,一直缓存在内存中,另一个原因就是前面文章提到的,为了实现退出功能,使用 了一个全局的ArrayList去存储所有新启动的Activity,导致Activity这种大对象无法释放,有这两个问题内存不堆积才有问题。

  定位到问题的所在后,先用前面的广播方式替换掉之前的那种方案,这样就解决了问题的一半了,那本地图片如何处理呢?就上网查看了一些文章,看到 许多大神都说到了软引用这个东东,于是就研究了下软引用如何使用。发现这软引用的确是个好东西。的确可以优化整个应用对内存的消耗。

  从JDK1.2开始,java将对象分成了四种级别,以达到程序对对象生财周期的灵活控制,这四个级别由强到弱是:强引用,软引用,弱引用,虚 引用。强引用就不多说了,就是我们平时直接new出来的一个对象,不做任何的修饰,就是强引用。虚引用暂未使用过也就没做过深入了解,弱引用的使用方式基 本和软引用是一样的,所以就重点看了一下应用程序如何使用软引用。

  如果一个对象只具有软引用,那么如果内存如果够用的话,GC就不会回收它,如果内存不足了,就会优先回收只有软引用的对象内存,而保证不会内存 溢出。基于软引用的这个特性,我们可以使用软引用来实现内存敏感区的高速缓存,因此为了防止内存溢出的发生,在处理一些占用内存较大且声明周期较长的对象 的时候,我们可以尽量使用软引用,例如: Context及其子类对象,Drawable及其子类对象,Bitmap位图对象等,在创建这些类的对象的时 候,尽量将其声明为软引用。

  软引用对象声明: SoftReference instance;

  下面两个例子是我在项目中实际使用的代码,大家可以看下。

代码片段一:

 //这个例子是用来处理生命周期较长的大对象

 /**********************************************************
* @文件名称:ActivityManager.java
* @创建时间:2014年11月6日 上午11:38:23
* @文件描述:Activity管理类
* @修改历史:2014年11月6日创建初始版本
**********************************************************/
public class ActivityManager
{
private static ActivityManager manager = null;
private static HashMap activityMap; // 静态语句块,在类加载的时候一起执行
static
{
manager = new ActivityManager();
activityMap = new HashMap();
} private ActivityManager()
{ } public static ActivityManager getInstance()
{
return manager;
} public void put(Activity act)
{
activityMap.put(act.toString(), new SoftReference(act));
} public void remove(Activity act)
{
activityMap.remove(act.toString());
} public void finishAllActivity()
{
Set set = activityMap.keySet();
Iterator iter = set.iterator();
while (iter.hasNext())
{
String actName = iter.next();
Activity currentAct = activityMap.get(actName).get();
if (currentAct != null)
{
currentAct.finish();
currentAct = null;
}
}
activityMap.clear();
activityMap = null;
}
}

代码片段二:

 //这个例子是用来处理位图等内存敏感对象示例
public class BitmapManager
{ private static BitmapManager bitmapManager = null;
private static HashMap> imageCache = null; static
{
bitmapManager = new BitmapManager();
imageCache = new HashMap>();
} private BitmapManager()
{ } public static BitmapManager getInstance()
{
return bitmapManager;
} public static void saveBitmapToCache(String path)
{
Bitmap bitmap = BitmapFactory.decodeFile(path);
// 添加该对象软引用对象到Map中使其缓存
imageCache.put(path, new SoftReference(bitmap));
// 使用完后手动将位图对象置null
bitmap = null;
} public static Bitmap queryBitmapByPath(String path)
{
// 取出软软引用
SoftReference softBitmap = imageCache.get(path);
// 使用时必须判断软引用是否回收,被回收返回空
if (softBitmap == null)
{
return null;
}
Bitmap bitmap = softBitmap.get(); return bitmap;
} }

总结:在我们开发应用程序时,最好是刚开始实现时就考虑到可能发生的问题,提前就做好这些细节性的处理,就会从根上杜绝这类问题的发生,而当问题发生了再去处理就会花费更多的精力。

android开发内存优化之软引用的更多相关文章

  1. Android开发——内存优化 图片处理

    8.  用缓存避免内存泄漏 很常见的一个例子就是图片的三级缓存结构,分别为网络缓存,本地缓存以及内存缓存.在内存缓存逻辑类中,通常会定义这样的集合类. private HashMap<Strin ...

  2. Android开发性能优化总结(一)

    安卓开发应用首先要讲究良好的用户体验,如果一款软件卡顿现象严重,不流畅,经常崩溃,那么将给用户带来极不良好的体验,从而损失用户. 在实际开发和学习中,我总结了一下关于安卓性能的优化,供大家参考交流. ...

  3. Android代码内存优化建议-OnTrimMemory优化

    原文  http://androidperformance.com/2015/07/20/Android代码内存优化建议-OnTrimMemory优化/ OnTrimMemory 回调是 Androi ...

  4. Android的内存优化

    腾讯公司在五月三十一日开展[腾讯Bugly移动开发人员沙龙]大会.大会上面叶方正老师解说了 关于Android的内存优化的问题,只是我感觉叶老师许多其它的站在了測试的角度上去解释了这一方面,叶老师给我 ...

  5. Android优化之软引用和弱引用

    Java从JDK1.2版本开始,就把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期.这四种级别由高到低依次为:强引用.软引用.弱引用和虚引用.这里重点介绍一下软引用和弱引用. 如果一 ...

  6. (转) Android开发性能优化简介

    作者:贺小令 随着技术的发展,智能手机硬件配置越来越高,可是它和现在的PC相比,其运算能力,续航能力,存储空间等都还是受到很大的限制,同时用户对手机的体验要求远远高于PC的桌面应用程序.以上理由,足以 ...

  7. [素材资源] Android开发性能优化简介(非常不错的)

    转自(http://www.starming.com/index.php?action=plugin&v=wave&tpl=union&ac=viewgrouppost& ...

  8. Android代码内存优化建议-Android官方篇

    转自:http://androidperformance.com/ http://developer.android.com/intl/zh-cn/training/displaying-bitmap ...

  9. Android 应用内存优化 之 onLowMemory & onTrimMemory

    OnLowMemory: 是Android提供的API,在系统内存不足,所有后台程序(优先级为background的进程,不是指后台运行的进程)都被杀死时,系统会调用OnLowMemory.OnTri ...

随机推荐

  1. 说说JDK中的String.valueOf()传null的诡异处理

    都说JDK的实现诡异多,今儿也算是被我踩到一个坑了. 就来说说关于String.valueOf的这个坑. public class TestString { public static void ma ...

  2. 第四篇 Flask 中的模板语言 Jinja2 及 render_template 的深度用法

    是时候开始写个前端了,Flask中默认的模板语言是Jinja2 现在我们来一步一步的学习一下 Jinja2 捎带手把 render_template 中留下的疑问解决一下 首先我们要在后端定义几个字符 ...

  3. C# 多线程窗体的创建

    从目前已经在项目中工作将近一个月来的情况来看,凡是费时的操作,基本上都要用到多线程的等待窗体.进度提示窗体等实时显示动态的进度信息.而如果直接在主线程的窗体上实时更新信息,就会造成更新太快或者太慢而出 ...

  4. 用C#操作IO端口1-用并口控制发光二极管

    什么是端口? 端口包含了一系列信号线, 通过这个端口CPU可以同其他外部设备交换数据, 比如我们经常见到的Modem,打印机等. 通常情况下, 打开的信号是”1”, 关闭的信号是”0”. 并口在同一时 ...

  5. Python 小练习三 发邮件

    import smtplib,os from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipar ...

  6. Hash表算法详解

    Hash表定义 散列表(Hash table,也叫哈希表),是根据关键字值(Key value)直接进行访问的数据结构.也就是说,它通过把关键字(关键字通过Hash算法生成)映射到表中一个位置来访问记 ...

  7. git 撤销 merging

    当我们在合代码的时候经常会遇到一些问题,这时候分支就处于merging状态,这时候可以用下面的命令撤销 $ git reset --hard HEAD (or sha_1) 不知道有没有更好的办法,希 ...

  8. 34. Search for a Range (Array; Divide-and-Conquer)

    Given a sorted array of integers, find the starting and ending position of a given target value. You ...

  9. 快速搭建Wordpress

    1. 下载:ZentaoPMS作为Mysql Apach Php的基础环境: 2. 下载:Wordpress安装包: 3. 将Wordpress解压,放置于ZentaoPMS的Xampp的htdocs ...

  10. poi导出excel表格

    package poiexcel; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; ...