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(软引用)
软引用是用来描述一些有用但并不是必需的对象,在内存严重不足的情况下会被系统回收,如果该对象可能会经常使用的,就尽量用软引用。
并且这个特性很适合用来实现缓存:比如网页缓存、图片缓存等。
以缓存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的性能的话,我们可以把哪些不常用并且占用内存比较大的对象用软引用或者弱引用来做缓存处理,鉴于保险起见,可以酌情选择使用弱引用还是软引用,实测下来二者被回收的概率相差无几。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值