从面试题中看java的Reference(引用)
作者:Harlber 发布时间:[ 2016/9/22 10:48:09 ] 推荐标签:测试开发技术 Java
常见的面试中会有这么一道题,“谈谈强引用、 软引用、 弱引用、虚引用”。
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来验证。下文是一个通过的测试案例。
@Test
public 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()); //'软可及'内存充足,不会被被回收
}
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.
通俗的说,弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。一个经典的弱引用的使用场景:哈希表的接口允许使用任何Java对象作为键来使用。当一个键值对被放入到哈希表中之后,哈希表对象本身有了对这些键和值对象的引用。如果这种引用是强引用的话,那么只要哈希表对象本身还存活,其中所包含的键和值对象是不会被回收的。如果某个存活时间很长的哈希表中包含的键值对很多,终有可能消耗掉JVM中全部的内存。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11