前言:四大引用,是一个古老的知识,今天看下

Harlber 授权公众号独家推送的文章,

Harlber 的简书地址 :http://www.jianshu.com/p/04b09d8a1745,也可点击阅读原文查看。

话不多说,进入正题:

常见的面试中会有这么一道题,“谈谈强引用、 软引用、 弱引用、虚引用”。

A:强引用,通过new出来的都是强引用
Q:那弱引用呢?
A:通过WeakReference构造出的,不再有强引用...
Q:那软引用呢,这些引用间的区别是什么?
A:...

面到这个阶段这就比较尴尬了。为了避免类似的尴尬,特地花了点时间去整理这些引用,以便下次面试的时候就这个问题能和面试官谈笑风生。

首先可以在oracle的文档中找到相应的api说明
java.lang.ref
Class Reference<T>

java.lang.Object
java.lang.ref.Reference<T>

Direct Known Subclasses:
PhantomReference, SoftReference, WeakReference

Abstract base class for reference objects. This class defines the operations common to all reference objects. Because reference objects are implemented in close cooperation with the garbage collector, this class may not be subclassed directly.
Since:1.2

事实上在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象。也就是说,只有对象处于可触及(reachable)状态,程序才能使用它。从JDK 1.2版本开始,把对象的引用分为4种级别,从而使程序能更加灵活地控制对象的生命周期。这4种级别由高到低依次为:强引用、软引用、弱引用和虚引用。

Strong Reference:
强引用是默认实现的引用。垃圾回收器不会回收具有强引用的对象,除非没有任何对象指向它时才会在一次GC 执行后被回收。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题
至此,也许犀利的你发现了这个现象:java中的Reference的子类中并没有一个叫StrongReference的,在文章中写的也是Strong Reference 。stackoverflow上也有类似的讨论,点击查看。

SoftReference:

Soft reference objects, which are cleared at the discretion of the garbage collector in response to memory demand. Soft references are most often used to implement memory-sensitive caches.Suppose that the garbage collector determines at a certain point in time that an object is softly reachable. At that time it may choose to clear atomically all soft references to that object and all soft references to any other softly-reachable objects from which that object is reachable through a chain of strong references. At the same time or at some later time it will enqueue those newly-cleared soft references that are registered with reference queues.
All soft references to softly-reachable objects are guaranteed to have been cleared before the virtual machine throws an OutOfMemoryError. Otherwise no constraints are placed upon the time at which a soft reference will be cleared or the order in which a set of such references to different objects will be cleared. Virtual machine implementations are, however, encouraged to bias against clearing recently-created or recently-used soft references.
Direct instances of this class may be used to implement simple caches; this class or derived subclasses may also be used in larger data structures to implement more sophisticated caches.As long as the referent of a soft reference is strongly reachable, that is, is actually in use, the soft reference will not be cleared.Thus a sophisticated cache can, for example, prevent its most recently used entries from being discarded by keeping strong referents to those entries, leaving the remaining entries to be discarded at the discretion of the garbage collector.

请留意文档中标注的片段

  • 软引用对象时刻响应着内存状态
    注意 这里并未明说内存不足时将回收软引用对象,内存充裕时则不会回收,待会儿的测试中就能应证这一点

  • 软引用常用于实现高速缓存。
    这里的缓存指的是高速内存缓存(区别于DiskLruCache)。

  • 所有引用了软可及(softly-reachable)的对象将在JVM抛出OutOfMemoryError异常前完成清除,回收工作。
    由此可见
    1.以SoftReference实现内存缓存是可靠的。
    2.软引用对象存在多种状态:软可及(softly-reachable)只是其中一种状态。

  • SoftReference可被用来实现简单的高速缓存;SoftReference类或派生子类也可用于较大的数据结构中实现更复杂的高速缓存。

  • 只要软引用对象是强可及(strongly reachabl) 在实际应用中软引用将不会被清除。

至此,我们可以通过一个简单的Test来验证。下文是一个通过的测试案例。

@Testpublic void softReference() {//测试环境,内存充足Object referent = new Object();SoftReference<Object> softRerference = new SoftReference<Object>(referent);assertSame(referent, softRerference.get());//referent '强可及'System.gc(); assertNotNull(softRerference.get());assertNotNull(referent); referent = null;//referent '软可及' System.gc();assertNotNull(softRerference.get()); //referent '软可及'|内存充足,不会被被回收}

WeakReference:

Weak reference objects, which do not prevent their referents from being made finalizable, finalized, and then reclaimed. Weak references are most often used to implement canonicalizing mappings.Suppose that the garbage collector determines at a certain point in time that an object is weakly reachable. At that time it will atomically clear all weak references to that object and all weak references to any other weakly-reachable objects from which that object is reachable through a chain of strong and soft references. At the same time it will declare all of the formerly weakly-reachable objects to be finalizable. At the same time or at some later time it will enqueue those newly-cleared weak references that are registered with reference queues.

  • 不论内存是否充裕,弱引用对象都将被回收

  • 弱引用不会阻扰引用对象进行finalizable,finalized还是reclaimed

  • 弱引用常用于实现canonicalizing mappings
    什么是canonicalizing mappings?在此引用一篇文章的解释。原文链接:http://c2.com/cgi/wiki?CanonicalizedMapping

A "canonicalized" mapping is where you keep one instance of the object in question in memory and all others look up that particular instance via pointers or somesuch mechanism. This is where weaks references can help. The short answer is that Weak Reference objects can be used to create pointers to objects in your system while still allowing those objects to be reclaimed by the garbage-collector once they pass out of scope.
通俗的说,弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。一个经典的弱引用的使用场景(请自行查阅WeakHashMap源码):哈希表的接口允许使用任何Java对象作为键来使用。当一个键值对被放入到哈希表中之后,哈希表对象本身就有了对这些键和值对象的引用。如果这种引用是强引用的话,那么只要哈希表对象本身还存活,其中所包含的键和值对象是不会被回收的。如果某个存活时间很长的哈希表中包含的键值对很多,最终就有可能消耗掉JVM中全部的内存。

同样的我们测试一下:

@Testpublic void weakReference() {Object referent = new Object();WeakReference<Object> weakRerference = new WeakReference<Object>(referent);     assertSame(referent, weakRerference.get());//referent '强可及'System.gc();assertNotNull(weakRerference.get());assertNotNull(referent);//referent '强可及' 不会被回收referent = null;//取消强引用,referent '弱可及' System.gc();assertNull(weakRerference.get()); //referent '弱可及'将被回收,此时内存充裕referent = null;System.gc(); assertNull(weakRerference.get()); //referent `不可及`}

'强可及','软可及' ,'弱可及' ,'不可及'这些引用状态简直看的人一脸懵逼呀。先不要慌,我们来看看oracle是怎么定义这些状态的:
Reachability
Going from strongest to weakest, the different levels of reachability reflect the life cycle of an object. They are operationally defined as follows:

  • An object is strongly reachable if it can be reached by some thread without traversing any reference objects. A newly-created object is strongly reachable by the thread that created it.
    An object is softly reachable if it is not strongly reachable but can be reached by traversing a soft reference.

  • An object is weakly reachable if it is neither strongly nor softly reachable but can be reached by traversing a weak reference. When the weak references to a weakly-reachable object are cleared, the object becomes eligible for finalization.

  • An object is phantom reachable if it is neither strongly, softly, nor weakly reachable, it has been finalized, and some phantom reference refers to it.

  • Finally, an object is unreachable, and therefore eligible for reclamation, when it is not reachable in any of the above ways.

Since:1.2
自然而然的Since 1.2 ,看下文档再对比下Test,现在应该明朗多了吧。
PhantomReference:

Phantom reference objects, which are enqueued after the collector determines that their referents may otherwise be reclaimed. Phantom references are most often used for scheduling pre-mortem cleanup actions in a more flexible way than is possible with the Java finalization mechanism.If the garbage collector determines at a certain point in time that the referent of a phantom reference is phantom reachable, then at that time or at some later time it will enqueue the reference.
In order to ensure that a reclaimable object remains so, the referent of a phantom reference may not be retrieved: The get method of a phantom reference always returns null.
Unlike soft and weak references, phantom references are not automatically cleared by the garbage collector as they are enqueued. An object that is reachable via phantom references will remain so until all such references are cleared or themselves become unreachable.

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

  • 虚引用主要用来跟踪对象被垃圾回收器回收的活动。

第一时间获得博客更新提醒,以及更多android干货,源码分析,欢迎关注我的微信公众号,扫一扫下方二维码或者长按识别二维码,即可关注。

从面试题中看Java的Reference(引用)相关推荐

  1. Java中各种引用(Reference)解析

    目录 1,引用类型 2, FinalReference 2.1, Finalizer 3, SoftReference 4, WeakReference 5, PhantomReference 6, ...

  2. java的弱引用_理解Java中的弱引用(Weak Reference)

    本篇文章尝试从What.Why.How这三个角度来探索Java中的弱引用,理解Java中弱引用的定义.基本使用场景和使用方法.由于个人水平有限,叙述中难免存在不准确或是不清晰的地方,希望大家可以指出, ...

  3. java byreference_深入理解Java中的引用(一)——Reference

    深入理解Java中的引用(一)--Reference 本系列文章首先会介绍Reference类,为之后介绍的强引用.软引用.弱引用和虚引用打下基础. 最后会介绍虚引用在DirectBuffer回收中的 ...

  4. [转载] Java中如何引用另一个类里的集合_Java工程师面试题整理

    参考链接: 在Java中将预定义的类名用作类或变量名 花了一星期把学过的都整理一遍 尽量易懂,从基础到框架 最新版大厂面经汇总出炉,持续更新中 汇总完了上传网盘,设计到后端架构师的一切知识 如果没更新 ...

  5. java 静态内部类 弱引用_Java基础 强引用、弱引用、软引用、虚引用

    前言 在ThreadLocal源码中,其中嵌套类ThreadLocalMap中的Entry继承了WeakReferenc.Java中提供这四种引用类型主要有两个目的:第一是可以让程序员通过代码的方式决 ...

  6. 一些面试题(JAVA)

    一些面试题(JAVA) 01.通过什么参数分配Java内存使用? java -Xms128m -Xmx512m 02.Treemap和Hashmap区别是什么? TreeMap对Key进行排序,而Ha ...

  7. @mapperscan mapper还是无法引用_高能来了!Java的四大引用

    文章很长文末有福利 Java中的四大引用 1. 强引用(StrongReference) 我们平常使用new操作符来创建的对象就是强引用对象,只要有一个引用存在,垃圾回收器永远不可能回收具有强引用的对 ...

  8. java comparable接口_Java面试题之Java集合篇三

    Java面试题之Java集合篇三1.HashMap和HashTable有何不同? (1)HashMap允许key和value为null,而HashTable不允许. (2)HashTable是同步的, ...

  9. java底层原理书籍_阿里面试题:Java中this和super关键字的底层实现原理

    知道的越多,不知道的就越多,业余的像一棵小草! 编辑:业余草 来源:https://www.xttblog.com/?p=5028 B 站:业余草 最近一个粉丝加我说,接到了阿里的面试,问问我阿里会面 ...

  10. java 四种内存_不可访问内存 Java四种引用包括强引用,软引用,弱引用,虚引用...

    小结: 1.不可访问内存是指一组没有任何可访问指针指向的由计算机程序进行动态分配的内存块. 2.垃圾收集器能决定是否一个对象还是可访问的:任何被确定不可访问的对象将会被释放. https://zh.w ...

最新文章

  1. 朱晔的互联网架构实践心得S1E9:架构评审一百问和设计文档五要素
  2. 【ajax 】同步、异步交互流程的区别
  3. 使用 core dump 查找程序遇到严重问题退出的原因
  4. iOS - Frame 项目架构
  5. angular6继承类注意几点:
  6. 国际智商测试皮肤软件,爆火的口服玻尿酸,是美容神器还是智商税?
  7. linux mysql服务器安装_Linux服务器MySQL安装
  8. Spark 之 故障排除(二)
  9. 使用scriptreference使你的页面加载更快
  10. 这是一篇测试博文的文章
  11. 数据库事务的4大特性与隔离级别
  12. mysql操作数据库进行封装实现增删改查功能
  13. 【Shiro第四篇】SpringBoot + Shiro实现记住登录状态
  14. N阶Butterworth滤波器的频率响应(Python实现)
  15. 后台打log(便于查看问题和调试)方法
  16. 3Q大战10年:丛林法则、黑暗森林与无限游戏
  17. echarts 省市区联动地图
  18. 微信转发指定的图文消息到朋友圈(JAVA版)
  19. python pandas csv 写文件_Pandas读写CSV文件的方法介绍(附代码)
  20. 数字功放-耐福NTP功放芯片详细性能概述

热门文章

  1. 新建xml模板_库卡机器人之OrangeEdit加模板
  2. php 32位检签,php crc32 计算字符串的 32 位 CRC(循环冗余校验)
  3. java 数据库按钮跳转_java,数据库的连接及基本操作
  4. Mybatis批量insert报错的解决办法【the right syntax to use near '' at line...】
  5. 对于scanf的新理解
  6. 基于LOAM框架的激光SLAM开源程序汇总
  7. 视觉三维重建中的关键技术及代码实现视频分享
  8. 强化学习中的各类算法
  9. react创建项目报错unexpected end of json while parsing near xxx
  10. 利用 SQL Monitor 查看语句运行状态步骤