目标的强

目标的强

对象的强、软、弱和虚引用 在JDK
1.2在先的本子中,若一个目的不被其他变量引用,那么程序就不可能再利用这么些目的。也就是说,唯有对象处于可触及(reachable)状态,程序才能动用它。从JDK
1.2本子开端,把目的的引用分为4种级别,从而使程序能越来越灵敏地操纵目的的生命周期。

Java4种引用的级别由高到低依次为:

强引用  >  软引用  >  弱引用  >  虚引用

 1.强引用(StrongReference)
  强引用是行使最广泛的引用。要是一个目的具备强引用,这垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序非凡终止,也不会靠随意回收具有强引用的靶子来缓解内存不足的题材。  ps:强引用其实也就是我们从来A
a = new A()这些意思。

2.软引用(SoftReference)
  如若一个目标只拥有软引用,则内存空间充分,垃圾回收器就不会回收它;倘若内存空间不足了,就会回收这个目的的内存。只要垃圾回收器没有回收它,该目的就足以被先后行使。软引用可用来实现内存敏感的高速缓存(下文给出示例)。
软引用可以和一个引用队列(ReferenceQueue)联合利用,要是软引用所引用的目标被垃圾回收器回收,Java虚拟机就会把这多少个软引用投入到与之提到的引用队列中。

3.弱引用(WeakReference)
  弱引用与软引用的界别在于:只具备弱引用的对象拥有更短命的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的进程中,一旦发觉了只享有弱引用的对象,不管当前内存空间充分与否,都会回收它的内存。但是,由于杂质回收器是一个优先级很低的线程,因而不必然会快速发现那么些只拥有弱引用的目的。
弱引用能够和一个引用队列(ReferenceQueue)联合利用,假设弱引用所引述的对象被垃圾回收,Java虚拟机就会把这么些弱引用加入到与之提到的引用队列中。

4.虚引用(PhantomReference)
“虚引用”顾名思义,就是形同虚设,与其它两种引用都不同,虚引用并不会控制对象的生命周期。如若一个目的仅具有虚引用,那么它就和没有任何引用一样,在其他时候都可能被垃圾回收器回收。
  虚引用重要用来跟踪对象被垃圾回收器回收的运动。虚引用与软引用和弱引用的一个界别在于:虚引用必须和引用队列
(ReferenceQueue)联合利用。当废品回收器准备回收一个对象时,假使发现它还有虚引用,就会在回收对象的内存往日,把这多少个虚引用投入到与之
关联的引用队列中。

ReferenceQueue queue = new ReferenceQueue ();

PhantomReference pr = new PhantomReference (object, queue); 
程序可以透过判断引用队列中是否业已进入了虚引用,来驾驭被引述的对象是否快要被垃圾回收。假如程序意识某个虚引用已经被投入到引用队列,那么就可以在所引用的对象的内存被回收在此以前运用必要的行走。

总结:

 

引用类型

被垃圾回收时间

   用途

   生存时间

强引用

从来不会

对象的一般状态

JVM停止运行时终止

软引用

在内存不足时

对象缓存

内存不足时终止

弱引用

在垃圾回收时

对象缓存

gc运行后终止

虚引用

Unknown

Unknown

Unknown

 

行使软引用构建敏感数据的缓存 1 干什么需要选择软引用
     
首先,我们看一个雇员音讯查询系统的实例。我们将运用一个Java语言实现的雇员消息查询系统查询存储在磁盘文件或者数据库中的雇员人事档案音讯。作为一个用户,我们一齐有可能需要回头去查看几分钟甚至几分钟前查看过的雇员档案音讯(同样,大家在浏览WEB页面的时候也通常会拔取“后退”按钮)。这时咱们一般会有二种程序实现形式:一种是把过去查看过的雇员信息保存在内存中,每一个存储了雇员档案信息的Java对象的生命周期贯穿整个应用程序始终;另一种是当用户起头翻看其他雇员的档案信息的时候,把囤积了当下所查看的雇员档案音讯的Java对象截止引用,使得垃圾收集线程可以回收其所占用的内存空间,当用户再一次索要浏览该雇员的档案新闻的时候,重新构建该雇员的信息。很肯定,第一种实现情势将导致大量的内存浪费,而第二种实现的老毛病在于就是垃圾收集线程还不曾开展垃圾收集,包含雇员档案音信的靶子依然完好无损地保存在内存中,应用程序也要再次构建一个目标。大家理解,访问磁盘文件、访问网络资源、查询数据库等操作都是潜移默化应用程序执行性能的重点元素,假使能重新取得那几个没有被回收的Java对象的引用,必将缩小不必要的造访,大大提升程序的运作速度。

2 倘若采用软引用
     
SoftReference的特色是它的一个实例保存对一个Java对象的软引用,该软引用的存在不妨碍垃圾收集线程对该Java对象的回收。也就是说,一旦SoftReference保存了对一个Java对象的软引用后,在垃圾线程对那个Java对象回收前,SoftReference类所提供的get()方法重临Java对象的强引用。此外,一旦垃圾线程回收该Java对象之后,get()方法将回到null。
看上面代码:

MyObject aRef = new MyObject();

SoftReference aSoftRef = new SoftReference(aRef); 

这儿,对于这多少个MyObject对象,有五个引用路径,一个是缘于SoftReference对象的软引用,一个起点变量aReference的强引用,所以这一个MyObject对象是强可及对象。
随后,我们可以了结aReference对这么些MyObject实例的强引用:

aRef = null;

其后,这多少个MyObject对象变成了软可及对象。即便垃圾收集线程举行内存垃圾收集,并不会因为有一个SoftReference对该目的的引用而一味保留该对象。Java虚拟机的杂质收集线程对软可及对象和另外一般Java对象开展了界别对待:软可及对象的清理是由垃圾收集线程遵照其一定算法按照内存需求决定的。也就是说,垃圾收集线程会在虚拟机抛出OutOfMemoryError往日回收软可及对象,而且虚拟机会尽可能优先回收长日子闲置不用的软可及对象,对那多少个刚刚构建的或碰巧使用过的“新”软可反对象会被虚拟机尽可能保留。在回收那些目的往日,我们得以因而:
MyObject anotherRef=(MyObject)aSoftRef.get(); 

双重拿到对该实例的强引用。而回收之后,调用get()方法就只可以取得null了。

3 使用ReferenceQueue清除失去了软引用对象的SoftReference
     
 作为一个Java对象,SoftReference对象除了具有保存软引用的特殊性之外,也存有Java对象的一般性。所以,当软可及对象被回收之后,即便这个SoftReference对象的get()方法再次来到null,但这一个SoftReference对象已经不再具有存在的市值,需要一个适度的破除机制,制止大量SoftReference对象带来的内存泄漏。在java.lang.ref包里还提供了ReferenceQueue。倘使在创制SoftReference对象的时候,使用了一个ReferenceQueue对象作为参数提供给SoftReference的构造方法,如:

ReferenceQueue queue = new ReferenceQueue();

人事档案,SoftReference ref = new
SoftReference(aMyObject, queue); 

这就是说当以此SoftReference所软引用的aMyOhject被垃圾收集器回收的同时,ref所强引用的SoftReference对象被列入ReferenceQueue。也就是说,ReferenceQueue中保存的目的是Reference对象,而且是早已错过了它所软引用的对象的Reference对象。另外从ReferenceQueue这些名字也得以见见,它是一个队列,当大家调用它的poll()方法的时候,如若这个行列中不是空队列,那么将回到队列前面的这个Reference对象。
在其余时候,我们都可以调用ReferenceQueue的poll()方法来检查是不是有它所关切的非强可及对象被回收。假设队列为空,将回来一个null,否则该措施重回队列中前边的一个Reference对象。利用这一个点子,我们能够检查哪个SoftReference所软引用的靶子已经被回收。于是我们得以把这一个失去所软引用的目的的SoftReference对象清除掉。常用的主意为:

SoftReference ref = null;

while ((ref = (EmployeeRef) q.poll()) != null) {

// 清除ref

}

 

 

参考:http://blog.csdn.net/mazhimazh/article/details/19752475

   http://www.cnblogs.com/skywang12345/p/3154474.html

admin

网站地图xml地图