首页 技术 正文
技术 2022年11月15日
0 收藏 646 点赞 3,680 浏览 3751 个字

前言:

从事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);
}}

第一次点击打印信息:

Android性能优化之巧用软引用与弱引用优化内存使用

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

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

Android性能优化之巧用软引用与弱引用优化内存使用

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

总结:

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

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,994
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,507
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,350
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,135
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,768
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,845