• 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html
  • 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html

Java中四种引用的区别

技术杂谈 勤劳的小蚂蚁 3个月前 (02-03) 77次浏览 已收录 0个评论 扫描二维码
在JDK 1.2之前,Java中的引用定义为:如果引用类型的数据中存储的数值代表的是另一块内存的起始地址,则这块内存即代表着一个引用。故在该定义下,一个Java对象仅有被应用和未被引用两种状态。
在JDK 1.2之后,Java对引用的概念进行了扩充,将引用分为强引用、软引用、弱引用和虚引用。这四种引用与Java虚拟机的垃圾回收机制紧密关联,建议重点关注。

Java中四种引用有什么区别?

参考答案:
Java将引用分为强引用、软引用、弱引用和虚引用四种,这四种引用强度依次逐渐减弱。
下面分别从四种引用的基本概念、具体实现、生命周期和应用场景四个方面进行对比分析。
强引用(Strong Reference):
  • 基本概念:在程序代码中普遍存在的,类似于“Object obj = new Object()”形式的引用。
  • 具体实现:创建一个对象并将其赋值给一个引用变量。
  • 生命周期:垃圾收集器永远不会回收掉强引用所关联着的对象,除非将该对象的所有引用全部置为null。
  • 应用场景:用的太多,以至于我说不出来(撒手状)。
软引用(Soft Reference):
  • 基本概念:描述一些还有用,但并非必需的对象。
  • 具体实现:JDK提供了SoftReference类来实现。
  • 生命周期:在系统将要发生内存溢出异常之前,将会把软引用所关联着的对象列进回收范围内并进行第二次回收,若回收后仍没有足够内存则抛出内存溢出异常。
  • 应用场景:用于实现内存敏感的高速缓存,如网页缓存和图片缓存等
注意:使用软引用能防止内存泄漏,增强程序的健壮性
弱引用(Weak Reference):
  • 基本概念:也描述非必需对象,强度比软引用更弱。
  • 具体实现:JDK提供了WeakReference类来实现。
  • 生命周期:无论系统内存是否足够,垃圾收集器工作时都会回收只被弱引用关联着的对象。
  • 应用场景:多将对象的弱引用作为HashMap的key值,以实现在不需要该对象时,只需要在程序中将其强引用置为null,而无需手动将其从HashMap中移除(由垃圾收集器实现,WeakHashMap即是基于该原理)。
虚引用(Phantom Reference):
  • 基本概念:也称幽灵引用或幻影引用,是最弱的一种引用关系。
  • 具体实现:JDK提供了PhantomReference类来实现。
  • 生命周期:虚引用并不会影响其所关联对象的生存时间,也无法通过虚引用来取得一个对象实例。
  • 应用场景:虚引用可以在对象被收集器回收时收到一个系统通知,即多用于在对象销毁前执行一些操作,如资源释放等。

扩展代码阅读

软引用的具体使用:
// 建立软引用并丢弃强引用
MyObject obj = new MyObject();
SoftReference softRef = new SoftReference(obj);
obj = null//丢弃强引用

// 通过软应用获取强引用
// 若软引用所关联的对象未被回收则重新获得强引用
// 若已被回收,则anotherObj = null
MyObject anotherObj = (MyObject)softRef.get();

/**
 * 若get()返回null,则说明软引用所关联的对象obj已被回收
 * 此时,softRef对象不再具有存在的价值
 * 可使用ReferenceQueue来将其清除,以避免发生内存泄漏
 */
MyObject obj = new MyObject();
ReferenceQueue queue = new ReferenceQueue();
SoftReference ref = new SoftReference(obj, queue);
obj = null;

// 若ref所关联的对象被回收,则ref会自动添加到queue队列中去。
弱引用的具体使用:与软引用雷同,其可以和一个引用对列(ReferenceQueue)联合使用,如果弱引用所关联的对象被JVM回收,该弱引用就会被添加到与之关联的引用对列中。
虚引用的具体使用:必须和引用对列关联使用,具体流程如下:
  • 对于虚引用所关联的对象,垃圾收集器工作时会将该虚引用添加到与之关联的引用对列中;
  • 程序通过判断引用对列中是否已经加入了虚引用,来了解被引用对象是否将要被回收;
  • 若将要被回收,则可以在其被回收之前采取必要的操作。
虚引用的测试代码如下:
Object obj = new Object();
ReferenceQueue queue = new ReferenceQueue ();
PhantomReference<Object> pf = new PhantomReference<Object>(obj, queue);
obj=null;

while(true){
    System.out.printf(“pf.get() = %d, isEnqueued: %brn”, pf.get(), pf.isEnqueued());
    if(pf.isEnqueued()) break;
    System.gc();
    Thread.sleep(1000);                
}

// pf.get() = null, isEnqueued: false
// pf.get() = null, isEnqueued: true

扩展面试题

问:Java将引用扩展为四种类型的目的是什么?
  • 有利于Java虚拟机进行垃圾回收;
  • 可以让程序员通过代码的方式来决定某些对象的生命周期。

丨极客文库, 版权所有丨如未注明 , 均为原创丨
本网站采用知识共享署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议进行授权
转载请注明原文链接:Java中四种引用的区别
喜欢 (0)
[247507792@qq.com]
分享 (0)
勤劳的小蚂蚁
关于作者:
温馨提示:本文来源于网络,转载文章皆标明了出处,如果您发现侵权文章,请及时向站长反馈删除。

您必须 登录 才能发表评论!

  • 精品技术教程
  • 编程资源分享
  • 问答交流社区
  • 极客文库知识库

客服QQ


QQ:2248886839


工作时间:09:00-23:00