android四大和作用场景,Android 四大引用的使用场景和区别

注:本文只是用于自己学习记录,内容来自网络相关文章。

943748d35092

image.png

在Android java.lang.ref包中包含SoftReference类、WeakReference类、PhantomReference类、ReferenceQueue类和Reference抽象类。

1、强引用

直接new出的对象:String str = new String("ABC");

1.1、强引用介绍

普遍使用的引用对象,但是即便内存不足时也不会通过回收机制来回收而导致程序奔溃

1.2、强引用的特点

强引用可以直接访问目标对象

强引用所指的对象在任何时候都不会被回收,即便jvm抛出oom

强引用可能会导致内存泄漏

2、软引用

SoftReference:软引用–>当虚拟机内存不足时,将会回收它指向的对象;需要获取对象时,可以调用get方法。

软引用对象不会很快被jvm回收,jvm 会根据当前堆的使用情况来判断何时回收,当堆的使用频率接近阀值时才会被回收

2.1、软引用的使用场景

例如从网络上获取图片,然后将获取的图片显示的同时,通过软引用缓存起来。当下次再去网络上获取图片时,首先会检查要获取的图片缓存中是否存在,若存在,直接取出来,不需要再去网络上获取。

2.2、基本用法

MySoftReference msf = new MySoftReference();

SoftReference sf = new SoftReference(msf);

MySoftReference mySoftReference =(MySoftReference) sf.get();

2.3、软引用的基本特点

2.3.1、描述

如果内存足够,软引用是不会被jvm回收的;

如果内存不够,会根据堆栈的使用情况来回收引用;

未被回收的软引用是一直可被程序占有的;

软引用可以和引用队列(ReferenceQueue)联合使用来实现内存紧张的高速缓存,

如果软引用引用的对象被回收,Java虚拟机会把改软引用对象加到与之关联的引用

队列中。eg:

ReferenceQueue rq = new ReferenceQueue();

SoftReference sf = new SoftReference(msf,rf);

当软引用对象被回收后,ReferenceQueue队列中存储着强引用的Reference,然后可通过poll()来判断当前引用队列是否有失去软引用的对象,如果队列为空,将返回一个null,否则该方法返回队列中前面的一个Reference对象。可以检测出哪个软引用对象被回收,然后将其清除。eg:

Reference reference =null;

while((reference==(EmployeeRef)rq.poll())){

//清除操作

reference =null;

System.gc();

}

2.3.2、使用场景

图片占用内存过大

View view = findViewById(***);

Bitmap bitmap =

BitmapFactory.decodeResource(getResource(),R.mipmap.ic_launcher);

Drawable drawable = new BitmapDrawable(bitmap);

SoftReference dsf = new SoftReference(drawable);

if(dsf!=null){

view.setImageResource(dsf.get())

}

解释:在使用软引用时直接通过get()获取到图片对象,当加载大量图片时,内存紧

张,软引用会被回收get()获取到的图片对象为null,(所以在使用软引用对象时一定

要判断非null,以免出现空指针异常)图片不显示。

使用软引用以后,在OutOfMemory异常发生之前,这些缓存的图片资源的内存空间

可以被释放掉的,从而避免内存达到上限,避免Crash发生。

3、弱引用

3.1、介绍:

WeakReference: 弱引用–>随时可能会被垃圾回收器回收,不一定要等到虚拟机内存不足

时才强制回收。要获取对象时,同样可以调用get方法。

3.2、特点:

如果当前引用只具备弱引用,那么在垃圾回收时,不管内存是否够用都会被回收,但垃圾回

收机制优先级低,一般不会被很快发现弱引用对象。

3.3、使用场景

避免内存泄漏 handler

这种情况就是由于android的特殊机制造成的:当一个android主线程被创建的时候,同时会

有一个Looper对象被创建,而这个Looper对象会实现一个MessageQueue(消息队列),当我

们创建一个handler对象时,而handler的作用就是放入和取出消息从这个消息队列中,每当

我们通过handler将一个msg放入消息队列时,这个msg就会持有一个handler对象的引用。

因此当Activity被结束后,这个msg在被取出来之前,这msg会继续存活,但是这个msg仍持有handler的引用,而handler在Activity中创建,会持有Activity的引用,因而当Activity结束后,Activity对象并不能够被gc回收,因而出现内存泄漏。

activity结束后,referenceQueue并不会结束,若这个队列中存在消息对象msg,而msg还持有handler引用,但activity已结束消息msg不能被处理,从而导致永久持有handler对象,而handler又依赖activity,所以发生内存泄漏。

java中所有非静态的对象都会持有当前类的强引用,而静态对象则只会持有当前类的弱引用。声明为静态后,handler将会持有一个Activity的弱引用,而弱引用会很容易被gc回收,这样就能解决Activity结束后,gc却无法回收的情况。eg:

MyHandler myHandler = new MyHandler(this);

public static class MyHandler extends Handler{

WeakReference ref;

MyHandler(ThisActivity activity){

ref = new WeakReference<>(activity);

}

}

4、虚引用 PhantomReference

虚引用是所有引用类型中最弱的一个。一个持有虚引用的对象,和没有引用几乎是一样的,随时都可能被垃圾回收器回收。当试图通过虚引用的get()方法取得强引用时,总是会失败。并且,虚引用必须和引用队列一起使用,它的作用在于跟踪垃圾回收过程。 当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在垃圾回收后,销毁这个对象,奖这个虚引用加入引用队列。Android实际开发中不用。

5、四种引用的区别

5.1 弱引用和软引用区别

弱引用与软引用的根本区别在于:只具有弱引用的对象拥有更短暂的生命周期,可能随时被回收。而只具有软引用的对象只有当内存不够的时候才被回收,在内存足够的时候,通常不被回收。

5.2 使用软引用或者弱引用防止内存泄漏

在Android应用的开发中,为了防止内存溢出,在处理一些占用内存大而且声明周期较长的对象时候,可以尽量应用软引用和弱引用技术。

软引用,弱引用都非常适合来保存那些可有可无的缓存数据。如果这样做,当系统内存不足时,这些缓存数据会被回收,不会导致内存溢出。而当内存资源充足时,这些缓存数据又可以存在相当长的时间。

5.3 到底什么时候使用软引用,什么时候使用弱引用呢?

个人认为,如果只是想避免OutOfMemory异常的发生,则可以使用软引用。如果对于应用的性能更在意,想尽快回收一些占用内存比较大的对象,则可以使用弱引用。

还有就是可以根据对象是否经常使用来判断。如果该对象可能会经常使用的,就尽量用软引用。如果该对象不被使用的可能性更大些,就可以用弱引用。

另外,和弱引用功能类似的是WeakHashMap。WeakHashMap对于一个给定的键,其映射的存在并不阻止垃圾回收器对该键的回收,回收以后,其条目从映射中有效地移除。WeakHashMap使用ReferenceQueue实现的这种机制。

943748d35092

image.png

·

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值