java.强引用软引用,java 强引用、软引用、弱引用、虚引用-Go语言中文社区

本文探讨了Java中的四种引用类型:强引用、软引用、弱引用和虚引用,阐述了它们的生命周期、使用场景和内存回收策略。重点介绍了如何通过这些引用控制内存释放,以及在Android、数据缓存和内存敏感场景中的应用实例。
摘要由CSDN通过智能技术生成

a11b264a366932d74dced5459e6f9b80.png

这篇文章的一个评论很有特点:

2eaf24eb031582355bf6561c8f0d44e4.png

强引用:

(一)强引用就是在程序代码之中普遍存在的,类似Object obj = new Object()这类的引用,

只要强引用还存在,垃圾收集器永远不会回收掉被引用的对象。只有当这个内存空间不被任何对象引用的时候,垃圾回收器才会去回收。

Object obj = new Object();// 强引用

String name = "漠天"; // 强引用

List list = new ArrayList();

list.add(name); // 强引用

obj、name、在list集合里的数据不会释放,即使内存不足也不会

(二)所以我们在使用完对象后,可以把对象置为空,这样我的垃圾回收器gc就会在合适的时候释放掉为该对象分配的内存空间

obj = null;

name = null;

list.clear();(ArrayList的clear方法是把list对象集合里的数据对象挨个置空 = null;但是list对象还在持有强引用,便于add新的数据)

list = null; // 再次把对象置空 彻底释放强引用

当然,在置为空前要确认是否不再需要使用该对象了,如果需要随时使用这个对象,则不能这么做,否则会出现空指针

(三)eg:

在android的生命周期使用完强引用后,在OnDestroy()里给判断并置空

软引用:

(一)在jvm报告内存不足之前会清除所有的软引用,这样的话gc就可以收集到很多软引用释放出来的内存空间,

从而解决内存吃紧的问题,避免内存溢出,什么时候被回收取决于gc的算法和gc运行时可用的内存大小。

软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收,

JAVA虚拟机就会把这个软引用加入到与之关联的引用队列中

String str = "zhuwentao"; // 强引用

SoftReference strSoft = new SoftReference(str); // 使用软引用封装强引用

(二) 弱引用是用来描述非必需对象的,可用来实现内存敏感的高速缓存

(三) 当内存足够大时可以把数组存入软引用,取数据时就可从内存里取数据,提高运行效率

软引用在实际中有重要的应用,例如浏览器的后退按钮。

按后退时,这个后退时显示的网页内容是重新进行请求还是从缓存中取出呢?这就要看具体的实现策略了。

(1)如果一个网页在浏览结束时就进行内容的回收,则按后退查看前面浏览过的页面时,需要重新构建

(2)如果将浏览过的网页存储到内存中会造成内存的大量浪费,甚至会造成内存溢出,这时候就可以使用软引用

弱引用:

(一)弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。

在垃圾回收器线程扫描它 所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。

不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。

String str = "漠天"; // 强引用

WeakReference strWeak = new WeakReference(str); // 使用弱引用封装强强引用

(二)弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。

Object c = new Car(); //只要c还指向car object, car object就不会被回收

WeakReference weakCar = new WeakReference(Car)(car);

当要获得weak reference引用的object时, 首先需要判断它是否已经被回收:

weakCar.get();//如果此方法为空, 那么说明weakCar指向的对象已经被回收了.

eg:if(weakCar.get()!=null){}

如果这个对象是偶尔的使用,并且希望在使用时随时就能获取到,但又不想影响此对象的垃圾收集,那么你应该用 Weak Reference 来记住此对象,而不是使用一般的Reference。

(三)例如 Handler 的弱引用,防止内存泄漏:

public class MainActivity extends AppCompatActivity {

private Handler handler ;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

handler = new MyHandler( this ) ;

new Thread(new Runnable() {

@Override

public void run() {

handler.sendEmptyMessage( 0 ) ;

}

}).start() ;

}

private static class MyHandler extends Handler {

WeakReference weakReference ;

public MyHandler(MainActivity activity ){

weakReference = new WeakReference( activity) ;

}

@Override

public void handleMessage(Message msg) {

super.handleMessage(msg);

if ( weakReference.get() != null ){

// update android ui

}

}

}

}

虚引用:

(一)“虚引用”顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。

如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。

虚引用主要用来跟踪对象被垃圾回收的活动。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列(ReferenceQueue)联合使用。

要注意的是,虚引用必须和引用队列关联使用,当垃圾回收器准备回收一个对象时,

如果发现它还有虚引用,就会把这个虚引用加入到与之 关联的引用队列中。

程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。

如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。

(二)使用:

ReferenceQueue queue = new ReferenceQueue();

PhantomReference pr = new PhantomReference(new User(), queue);

System.out.println(pr.get());

注意:

特别注意,在实际程序设计中一般很少使用弱引用与虚引用,使用软用的情况较多,

这是因为软引用可以加速JVM对垃圾内存的回收速度,可以维护系统的运行安全,防止内存溢出(OutOfMemory)等问题的产生。

转载文章总结:

强引用:

String str = “abc”;

list.add(str);

软引用:

如果弱引用对象回收完之后,内存还是报警,继续回收软引用对象

弱引用:

如果虚引用对象回收完之后,内存还是报警,继续回收弱引用对象

虚引用:

虚拟机的内存不够使用,开始报警,这时候垃圾回收机制开始执行System.gc(); String s = “abc”;如果没有对象回收了, 就回收没虚引用的对象

个人感觉:

强引用:

平常使用的对象,使用注意及时置空释放即可

软引用:

使用软引用队列处理比较吃内存的对象,比如:处理图片加载、文件下载、缓存大量数据到内存等

弱引用和虚引用:自己用作练习和测试即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值