java学习之路----什么是java的弱引用

 Java从1.2版本开始引入了4种引用,这4种引用的级别由高到低依次为:

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

⑴强引用(StrongReference)
   强引用是使用最普遍的引用。如果一个对象具有强引用,那垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。

⑵软引用(SoftReference)

   如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。

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

⑶弱引用(WeakReference)

   弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。

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

⑷虚引用(PhantomReference)

   “虚引用”顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。

   虚引用主要用来跟踪对象被垃圾回收器回收的活动。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列 (ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之 关联的引用队列中。


由于引用和内存回收关系紧密。下面,先通过实例对内存回收有个认识;然后,进一步通过引用实例加深对引用的了解。
我们首先来建立一个类:
public  class  MyDate  extends  Date{
      public  MyDate(){
          
     }
     
      //我们来重写finalize,因为finalize函数 在JvM回收内存的时候会调用,但是JVM并不保证回收的时候一定会调用
     
      @Override
      protected  void  finalize()  throws  Throwable {
     
            super .finalize();
          
          System.  out .println( this  .getTime());
     }

      @Override
      public  String toString() {
     
            return  "Date"  + this .getTime();
     }
          
}

再来建立一个消耗内存的测试类

      public  class  ReferenceTest {
      public  ReferenceTest(){
          
     }
      //这个方法的目的是来消耗内存
      public  static  void  drainMemory(){
          String array[]=  new  String[1024*10];
            for ( int  i=0;i<1024*10;i++){
                for ( int  j= 'a'  ;j< 'z'  ;j++){
                   array[i]=array[i]+(  char )j;
              }
          }
     }
     
}

我们下面来分情况来测试一下

1.清除对象
public  class  Test {
      public  static  void  main(String[] args) {
          MyDate myDate= new  MyDate();
          myDate=  null ;
     }

}

结果无输出

说明date=null,但是JVM并没有执行垃圾回收操作

2.显示的调用垃圾回收

public  class  Test {
      public  static  void  main(String[] args) {
          MyDate myDate= new  MyDate();
          myDate=  null ;
          System. gc();//设为空后,去自动调用垃圾回收
     }

}
结果:
1386430828594

说明垃圾回收机制调用了finalize()方法

3.隐式的调用垃圾回收
public  class  Test {
      public  static  void  main(String[] args) {
          MyDate myDate= new  MyDate();
          myDate=  null ;
          ReferenceTest. drainMemory(); //我们来造成内存的大量消耗
     }

}

结果:
1386431068074


说明调用了垃圾回收机制(内存的大量消耗造成了垃圾回收自动调用),我们得出结论,在内存充足的情况下,除非你显示的调用垃圾回收机制,否则它不会进行垃圾回收,在内存不足的情况下,JVM会自动调用垃圾回收


我们在来看看java对引用的分类

      强引用:

      public  class  Test {
      public  static  void  main(String[] args) {
          MyDate myDate= new  MyDate();//强引用
          System. gc();
     }

}
结果:
无输出,说明虽然我们显示的调用了垃圾回收,但是mydate是强引用,所以不会被回收

     软引用

public  class  Test {
      public  static  void  main(String[] args) {
           SoftReference ref = new  SoftReference( new  MyDate()); //创建一个软引用
          ReferenceTest. drainMemory();
     }

}

结果无所出:

说明在内存不足的情况下,软引用会被停止

弱引用:

public  class  Test {
      public  static  void  main(String[] args) {
           WeakReference ref = new  WeakReference( new  MyDate());
          ReferenceTest. drainMemory();
     }

}

结果:
1386431868012

说明在J垃圾回收的时候,弱引用被停止

虚引用:
public  class  Test {
      public  static  void  main(String[] args) {
     
           ReferenceQueue queue= new  ReferenceQueue();
          
           PhantomReference ref = new  PhantomReference( new  MyDate(), queue);
            //ReferenceTest.drainMemory();
          
     System.gc();
     }

}
结果:
1386432527842

说明对象在创建完成之后,就被垃圾回收了





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值