Android性能优化之巧用软引用与弱引用优化内存使用
前言:
从事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性能优化之巧用软引用与弱引用优化内存使用的更多相关文章
- [Android] Android开发优化之——使用软引用和弱引用
Java从JDK1.2版本开始,就把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期.这四种级别由高到低依次为:强引用.软引用.弱引用和虚引用. 这里重点介绍一下软引用和弱引用. ...
- Android开发优化之——使用软引用和弱引用
Java从JDK1.2版本开始,就把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期.这四种级别由高到低依次为:强引用.软引用.弱引用和虚引用. 这里重点介绍一下软引用和弱引用. 如果 ...
- Android性能提升之强引用、软引用、弱引用、虚引用使用
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52637333 背景:收到公众投稿 ...
- Android优化之软引用和弱引用
Java从JDK1.2版本开始,就把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期.这四种级别由高到低依次为:强引用.软引用.弱引用和虚引用.这里重点介绍一下软引用和弱引用. 如果一 ...
- 九、Android学习笔记_ Android开发中使用软引用和弱引用防止内存溢出
在<Effective Java 2nd Edition>中,第6条“消除过期的对象引用”提到,虽然Java有 垃圾回收机制,但是只要是自己管理的内存,就应该警惕内存泄露的问题,例如的对象 ...
- Android学习笔记_78_ Android开发中使用软引用和弱引用防止内存溢出
在<Effective Java 2nd Edition>中,第6条“消除过期的对象引用”提到,虽然Java有 垃圾回收机制,但是只要是自己管理的内存,就应该警惕内存泄露的问题,例如的对象 ...
- Java 如何有效地避免OOM:善于利用软引用和弱引用
Java 如何有效地避免OOM:善于利用软引用和弱引用 想必很多朋友对OOM(OutOfMemory)这个错误不会陌生,而当遇到这种错误如何有效地解决这个问题呢?今天我们就来说一下如何利用软引用和弱引 ...
- Java 对象引用方式 —— 强引用、软引用、弱引用和虚引用
Java中负责内存回收的是JVM.通过JVM回收内存,我们不需要像使用C语音开发那样操心内存的使用,但是正因为不用操心内存的时候,也会导致在内存回收方面存在不够灵活的问题.为了解决内存操作不灵活的问题 ...
- 通过软引用和弱引用提升JVM内存使用性能的方法(面试时找机会说出,一定能提升成功率)
初学者或初级程序员在面试时如果能证明自己具有分析内存用量和内存调优的能力,这相当有利,因为这是针对5年左右相关经验的高级程序员的要求.而对于高级程序员来说,如果能在面试时让面试官感觉你确实做过内存调优 ...
随机推荐
- 苹果强制使用HTTPS传输了怎么办?——关于HTTPS,APP开发者必须知道的事
WeTest 导读 2017年1月1日起,苹果公司将强制使用HTTPS协议传输.本文通过对HTTPS基础原理和通信过程内容的讲解,介绍APP开发者在这个背景下的应对办法. 几周前,我们在<htt ...
- 自己实现一个javascript事件模块
nodejs中的事件模块 nodejs中有一个events模块,用来给别的函数对象提供绑定事件.触发事件的能力.这个别的函数的对象,我把它叫做事件宿主对象(非权威叫法),其原理是把宿主函数的原型链指向 ...
- JavaScript模仿块级作用域
avaScript 没有块级作用域的概念.这意味着在块语句中定义的变量,实际上是在包含函数中而非语句中创建的,来看下面的例子: function outputNumbers(count){ for ( ...
- AI人工智能系列随笔
初探 AI人工智能系列随笔:syntaxnet 初探(1)
- Linux基础介绍【第三篇】
更改SSH服务端远程登录的配置 windows服务端的默认远程管理端口是3389,管理员用户是administrator,普通用户是guest.Linux的管理用户是root,普通用户默认有很多个,远 ...
- Linux 入门之网络配置
查看网络状态 ifconfig 修改网络参数 实验环境centos6.5,其他系统自行百度 ls /etc/sysconfig/network-scripts 显示所有文件, vi /etc/sysc ...
- Web 项目杂记(一)
1.Tomcat 多实例部署 在Tomcat下多实例部署后,发现如下问题,采用etc/init.d/tomcat start方式无法启动,而需要采用startup.sh.查找原因发现,是因为多实例部署 ...
- Cocos2d-x不要随便在onEnter里面addChild
使用任何版本的Cocos2d-x(1.x,2.x,3.0),在onEnter中调用addChild,都要小心谨慎,因为它有可能导致两种莫名其妙的BUG,莫名其妙的BUG当然难以定位了!更何况这个BUG ...
- Git入门资料汇总
Git是一个非常好用的版本控制工具,同时,它也是一个相对比较复杂的工具,想要掌握它还是需要花一番功夫的.网络上关于Git的入门资料已经很多了,我就不再重复了,直接把我学习的文章放在这里. Git详解 ...
- DevExpress学习系列(控件篇):GridControl的基本应用
一般属性设置 不显示分组框:Gridview->Option View->Show Group Panel=false 单元格不可编辑:gridcontrol -->gridview ...