前言:

从事Android开发的同学都知道移动设备的内存使用是非常敏感的话题,今天我们来看下如何使用软引用与弱引用来优化内存使用。下面来理解几个概念。

1.StrongReference(强引用)

强引用是我们最最常见的一种,一般我们在代码中直接通过new出来的对象等,都是强引用,强引用只要存在没有被销毁,内存就不会被系统回收。我们以生成Bitmap为例如下:

Bitmap imageBitmap = readBitmapFromResource(getResources(), R.mipmap.bg_post_activity_5);

生成Bitmap代码:

    public Bitmap readBitmapFromResource(Resources resources, int resourcesId) {
BitmapFactory.Options options = new BitmapFactory.Options();
return BitmapFactory.decodeResource(resources, resourcesId, options);
}

2.SoftReference(软引用)

软引用是用来描述一些有用但并不是必需的对象,在内存严重不足的情况下会被系统回收,如果该对象可能会经常使用的,就尽量用软引用。因此,这一点可以很好地用来解决OOM的问题,并且这个特性很适合用来实现缓存:比如网页缓存、图片缓存等。这里还是以缓存Bitmap为例:

 SoftReference<Bitmap> softReference = new SoftReference<Bitmap>(readBitmapFromResource(getResources(), R.mipmap.bg_post_activity_5));
Bitmap bitmap = softReference.get();

3.WeakReference(弱引用)

弱引用也是用来描述非必需对象的,当JVM进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象,WeakReference 的强度又明显低于 SoftReference,所以如果该对象不被使用的可能性更大些,就可以用弱引用。还是以缓存Bitmap为例:

 WeakReference<Bitmap> weakReference = new WeakReference<Bitmap>(readBitmapFromResource(getResources(), R.mipmap.bg_post_activity_5));
Bitmap bitmap1 = weakReference.get();

4.PhantomReference(虚引用)

虚引用和前面的软引用、弱引用不同,它并不影响对象的生命周期。如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收。还是以缓存Bitmap为例:

 ReferenceQueue<Bitmap> queue = new ReferenceQueue<Bitmap>();
PhantomReference<Bitmap> phantomReference = new PhantomReference<Bitmap>(readBitmapFromResource(getResources(), R.mipmap.bg_post_activity_5),queue);
Bitmap bitmap2 = phantomReference.get();

5.几种引用被回收概念测试

从上面的分析可以看出内存被系统回收的概率从小到大是:虚引用--弱引用--软引用--强引用,我们写个程序来验证一下。

public class MainActivity extends AppCompatActivity {
private LinearLayout request_layout;
private PhantomReference<Bitmap> phantomReference;
private WeakReference<Bitmap> weakReference;
private SoftReference<Bitmap> softReference;
private Bitmap strongReference; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
request_layout = (LinearLayout) findViewById(R.id.request_layout); findViewById(R.id.request_btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
testReference();
}
});
} private void testReference() {
//模拟内存使用 往一个布局中不断加入ImageView来模拟内存使用
ImageView imageView = new ImageView(this);
Bitmap imageBitmap = readBitmapFromResource(getResources(), R.mipmap.bg_post_activity_5);
imageView.setImageBitmap(imageBitmap);
request_layout.addView(imageView); if (strongReference == null) {
strongReference = readBitmapFromResource(getResources(), R.mipmap.bg_post_activity_5);
}
Log.e("Reference", "StrongReference---->" + strongReference);
if (softReference == null) {
softReference = new SoftReference<Bitmap>(readBitmapFromResource(getResources(), R.mipmap.bg_post_activity_5));
}
Bitmap bitmap = softReference.get();
Log.e("Reference", "SoftReference---->" + bitmap); if (weakReference == null) {
weakReference = new WeakReference<Bitmap>(readBitmapFromResource(getResources(), R.mipmap.bg_post_activity_5));
}
Bitmap bitmap1 = weakReference.get();
Log.e("Reference", "WeakReference---->" + bitmap1); if (phantomReference == null) {
ReferenceQueue<Bitmap> queue = new ReferenceQueue<Bitmap>();
phantomReference = new PhantomReference<Bitmap>(readBitmapFromResource(getResources(), R.mipmap.bg_post_activity_5), queue);
}
Bitmap bitmap2 = phantomReference.get();
Log.e("Reference", "PhantomReference---->" + bitmap2);
} public Bitmap readBitmapFromResource(Resources resources, int resourcesId) {
BitmapFactory.Options options = new BitmapFactory.Options();
return BitmapFactory.decodeResource(resources, resourcesId, options);
} }

第一次点击打印信息:

通过打印信息可以虚引用直接回收掉了,或者可以说直接不存在引用。

接下来多次点击打印信息:

在模拟内存使用越来越紧张的情况下,并没有出现先回收弱引用,再回收软引用,而是两个一并回收掉了,其实按照Java正常引用顺序是软引用强于弱引用,但是从 Android 2.3 (API Level 9)开始,垃圾回收器会更倾向于回收持有软引用或弱引用的对象,这让软引用像弱引用一样变得不再可靠。所以图片缓存不再使用软引用而采用LRU算法。但是强引用一直毅力不倒。

总结:

从上面的介绍及测试对比可以得知,如果我们比较在意APP的性能的话,我们可以把哪些不常用并且占用内存比较大的对象用软引用或者弱引用来做缓存处理,鉴于保险起见,可以酌情选择使用弱引用还是软引用,实测下来二者被回收的概率相差无几。

Android性能优化之巧用软引用与弱引用优化内存使用的更多相关文章

  1. [Android] Android开发优化之——使用软引用和弱引用

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

  2. Android开发优化之——使用软引用和弱引用

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

  3. Android性能提升之强引用、软引用、弱引用、虚引用使用

    转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52637333 背景:收到公众投稿 ...

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

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

  5. 九、Android学习笔记_ Android开发中使用软引用和弱引用防止内存溢出

    在<Effective Java 2nd Edition>中,第6条“消除过期的对象引用”提到,虽然Java有 垃圾回收机制,但是只要是自己管理的内存,就应该警惕内存泄露的问题,例如的对象 ...

  6. Android学习笔记_78_ Android开发中使用软引用和弱引用防止内存溢出

    在<Effective Java 2nd Edition>中,第6条“消除过期的对象引用”提到,虽然Java有 垃圾回收机制,但是只要是自己管理的内存,就应该警惕内存泄露的问题,例如的对象 ...

  7. Java 如何有效地避免OOM:善于利用软引用和弱引用

    Java 如何有效地避免OOM:善于利用软引用和弱引用 想必很多朋友对OOM(OutOfMemory)这个错误不会陌生,而当遇到这种错误如何有效地解决这个问题呢?今天我们就来说一下如何利用软引用和弱引 ...

  8. Java 对象引用方式 —— 强引用、软引用、弱引用和虚引用

    Java中负责内存回收的是JVM.通过JVM回收内存,我们不需要像使用C语音开发那样操心内存的使用,但是正因为不用操心内存的时候,也会导致在内存回收方面存在不够灵活的问题.为了解决内存操作不灵活的问题 ...

  9. 通过软引用和弱引用提升JVM内存使用性能的方法(面试时找机会说出,一定能提升成功率)

    初学者或初级程序员在面试时如果能证明自己具有分析内存用量和内存调优的能力,这相当有利,因为这是针对5年左右相关经验的高级程序员的要求.而对于高级程序员来说,如果能在面试时让面试官感觉你确实做过内存调优 ...

随机推荐

  1. 在 ML2 中配置 OVS flat network - 每天5分钟玩转 OpenStack(133)

    前面讨论了 OVS local network,今天开始学习 flat network. flat network 是不带 tag 的网络,宿主机的物理网卡通过网桥与 flat network 连接, ...

  2. 干货分享:让你分分钟学会 JS 闭包

    闭包,是 Javascript 比较重要的一个概念,对于初学者来讲,闭包是一个特别抽象的概念,特别是ECMA规范给的定义,如果没有实战经验,很难从定义去理解它.因此,本文不会对闭包的概念进行大篇幅描述 ...

  3. Bootstrap-Select 动态加载数据的小记

    关于前端框架系列的可以参考我我刚学Bootstrap时候写的LoT.UI http://www.cnblogs.com/dunitian/p/4822808.html#lotui bootstrap- ...

  4. 【初学python】使用python连接mysql数据查询结果并显示

    因为测试工作经常需要与后台数据库进行数据比较和统计,所以采用python编写连接数据库脚本方便测试,提高工作效率,脚本如下(python连接mysql需要引入第三方库MySQLdb,百度下载安装) # ...

  5. 算法与数据结构(七) AOV网的拓扑排序

    今天博客的内容依然与图有关,今天博客的主题是关于拓扑排序的.拓扑排序是基于AOV网的,关于AOV网的概念,我想引用下方这句话来介绍: AOV网:在现代化管理中,人们常用有向图来描述和分析一项工程的计划 ...

  6. document.compatMode

    在我电脑屏幕上显示的 电脑是 1920*1080这是在document.compatMode:css1Compat模式 window.screen.availWidth 1920 window.scr ...

  7. “此网页上的某个 Web 部件或 Web 表单控件无法显示或导入。找不到该类型,或该类型未注册为安全类型。”

    自从vs装了Resharper,看见提示总是手贱的想去改掉它.于是乎手一抖,把一个 可视web部件的命名空间给改了. 喏,从LibrarySharePoint.WebPart.LibraryAddEd ...

  8. HTML5游戏源码 飞翔的字母 可自定义内容

    相信大家都玩过飞翔的小鸟吧,当然,可能已经有很多人因为这个游戏砸了不少手机.吼吼. 废话不多说,回到主题,源码如下. 博客园上传空间大小有限制,没法上传了,需要打包源码的朋友们请留言邮箱地址.当然还有 ...

  9. KVM安装部署

    KVM安装部署 公司开始部署KVM,KVM的全称是kernel base virtual machine,对KVM虚拟化技术研究了一段时间, KVM是基于硬件的完全虚拟化,跟vmware.xen.hy ...

  10. 对一致性Hash算法,Java代码实现的深入研究

    一致性Hash算法 关于一致性Hash算法,在我之前的博文中已经有多次提到了,MemCache超详细解读一文中"一致性Hash算法"部分,对于为什么要使用一致性Hash算法.一致性 ...