前言:

从事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. ElasticSearch 5学习(9)——映射和分析(string类型废弃)

    在ElasticSearch中,存入文档的内容类似于传统数据每个字段一样,都会有一个指定的属性,为了能够把日期字段处理成日期,把数字字段处理成数字,把字符串字段处理成字符串值,Elasticsearc ...

  2. ASP.NET Core CORS 简单使用

    CORS 全称"跨域资源共享"(Cross-origin resource sharing). 跨域就是不同域之间进行数据访问,比如 a.sample.com 访问 b.sampl ...

  3. 在Visual Studio Code中配置GO开发环境

    一.GO语言安装 详情查看:GO语言下载.安装.配置 二.GoLang插件介绍 对于Visual Studio Code开发工具,有一款优秀的GoLang插件,它的主页为:https://github ...

  4. .NET应用程序域

    在.NET平台下,可执行程序并没有直接承载在Windows进程中,而非托管程序是直接承载的..NET可执行程序承载在进程的一个逻辑分区中,称之为应用程序域(AppDomain).一个进程可以包含多个应 ...

  5. PHP static静态属性和静态方法

    这里分析了php面向对象中static静态属性和静态方法的调用.关于它们的调用(能不能调用,怎么样调用),需要弄明白了他们在内存中存放位置,这样就非常容易理解了.静态属性.方法(包括静态与非静态)在内 ...

  6. CSS3 @keyframes 动画

    CSS3的@keyframes,它可以取代许多网页动画图像,Flash动画,和JAVAScripts. CSS3的动画属性 下面的表格列出了 @keyframes 规则和所有动画属性: 浏览器支持 表 ...

  7. BZOJ3198[SDOI2013]SPRING

    Description Input Output Sample Input 3 3 1 2 3 4 5 6 1 2 3 0 0 0 0 0 0 4 5 6 Sample Output 2 HINT 题 ...

  8. .NET跨平台之旅:将示例站点升级至 .NET Core 1.1 Preview 1

    今天微软发布了 .NET Core 1.1 Preview 1(详见 Announcing .NET Core 1.1 Preview 1 ),紧跟 .NET Core 前进的步伐,我们将示例站点 h ...

  9. 用Taurus.MVC 做个企业站(上)

    前言: 之前是打算写一篇文章叫:Taurus.MVC 从入门到精通,一篇完事篇! 后来转指一念,还是把教程集在这个企业站项目上吧!!! 企业站风格: 之前发过一个帮师妹写的企业站:最近花了几个夜晚帮师 ...

  10. NodeJs 开发微信公众号(三)微信事件交互

    微信公众号有个规则,一旦开启了开发者模式,其他的常规功能就都必须通过接口调用完成.比如说自定义菜单功能,必须通过发送post请求的方式生成.本章就通过关注到取消关注的整个过程来谈一谈nodejs是怎么 ...