Java引用对象SoftReference WeakReference PhantomReference

对于这个做开发没有用到过,查网上可以用来做“高内存压力的缓存”,不懂,做个标识以后再看一下.

之前一直没有接触过弱引用这个概念,今天看到以后觉得挺新鲜,就查了查资料总结一下,希望对大家有所帮助。
 要理解弱引用,首先要先了解一下强引用(Strong Reference),  其实我之前也并不了解强引用,虽然天天都在用。举例来说:
         

  1. String abc =  new  String ( "abcdf" );
这 就是创建了一个String的实例然后在变量abc中保存一个强引用,为什么说它强(Strong)呢?这是跟垃圾回收器相关的,如果一个对象是通过强引 用链(Chain of Strong Reference) 访问到的,也就是像上面那样,那么这个对象是不会被垃圾回收器回收的, 这在正常情况下是正确的,因为你不想垃圾回收器回收你正在使用的对象。当内存空间不足时,Java虚拟机宁愿抛出OutOfMemory错误,是程序异常 终止,也不会为了解决内存不足而回收这类引用的对象。这就是使用强引用的一个问题, 强引用的另外一个常见的问题就是缓存, 特别是对于那些非常大的数据结构,像图片等等,平差情况下我们是希望程序能缓存这些大的数据结构的,因为重新加载非常耗费服务器资源。因为缓存就是为了避 免重新加载这些大的数据结构的,所以缓存中会保存一个指向内存中数据结构的引用,而这些引用通常都是强引用,所以这些引用会强迫这些大的数据结构保存在内 存中,除非用通过某些方法户知道哪一个数据结构不再需要保存在内存中了,然后再把他从缓存中清除。

弱引用就是不保证不被垃圾回收器回收的对象,它拥有比较短暂的生命周期,在垃圾回收器扫描它所管辖的内存区域过程中,一旦发现了只具有弱引用的对象,就会回收它的内存,不过一般情况下,垃圾回收器的线程优先级很低,也就不会很快发现那些只有弱引用的对象。

弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用的对象被垃圾回收的话,Java虚拟机就会把这个弱引用加入相关的引用队列中。
一下就是创建弱引用对象的例子。
  1. String abc =  new  String( "abcde" );
  2. WeakReference<String> wf=  new  WeakReference<String>(str, rq);

String abc1 = wf.get()//如果abcde这个对象没有被垃圾回收器回收,那么abc1就指向"abcde"对象

==========================================

Java 平台引用

一、创建类 MyDate

public class MyDate extends Date {

   

     /** Creates a new instance of MyDate */

     public MyDate() {

     }

 

     protected void finalize() throws Throwable {

         super.finalize();

         System.out.println("obj [Date: " + this.getTime() + "] is gc");

     }   

 

     public String toString() {

         return "Date: " + this.getTime();

     }

}

在这个类中,对 java.util.Date 类进行了扩展,并重写了 finalize() toString() 方法。

注: finalize() 方法在 JVM 销毁对象时运行这个方法, finalize() 方法不能保证一定被 JVM 执行。

二、创建测试类 ReferenceTest

public class ReferenceTest {   

     /** Creates a new instance of ReferenceTest */

     public ReferenceTest() {

     }

   

     /**

      * @param args the command line arguments

      */

     public static void main(String[] args) {

       

     }

     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] += (char)j;

             }           

         }

     }

}

在这个类中定义了一个静态方法 drainMemory() ,此方法旨在消耗大量的内存,促使 JVM 运行垃圾回收。

三、 JVM 什么时候运行垃圾回收

1 、没有调用垃圾回收:

main 中添加如下代码:

public static void main(String[] args) {

         MyDate date = new MyDate();

         date = null;

}

运行程序:

< 无任何输出 >

解释: date 虽然被置位 null ,但由于 JVM 没有执行垃圾回收操作, MyDate finalize() 方法没有被运行

2 、显式调用垃圾回收:

main 中添加如下代码:

public static void main(String[] args) {

         MyDate date = new MyDate();

         date = null;

         System.gc();

}

运行程序:

obj [Date: 1207972662525] is gc

解释:调用了 System.gc() ,使 JVM 运行垃圾回收, MyDate finalize() 方法被运行

3 、隐式调用垃圾回收:

main 中添加如下代码:

public static void main(String[] args) {

         MyDate date = new MyDate();

         date = null;

         drainMemory();

}

解释:虽然没有显式调用垃圾回收方法 System.gc() ,但是由于运行了耗费大量内存的方法,触发 JVM 进行垃圾回收。

总结: JVM 的垃圾回收机制,在内存充足的情况下,除非你显式调用 System.gc() ,否则它不会进行垃圾回收;在内存不足的情况下,垃圾回收将自动运行

四、 Java 对引用的分类

级别

什么时候被垃圾回收

用途

生存时间

从来不会

对象的一般状态

JVM 停止运行时终止

在内存不足时

对象简单?缓存

内存不足时终止

在垃圾回收时

对象缓存

gc 运行后终止

假象

Unknown

Unknown

Unknown

1 、强引用:

public static void main(String[] args) {

         MyDate date = new MyDate();

         System.gc();

}

解释:即使显式调用了垃圾回收,但是用于 date 是强引用, date 没有被回收

2 、软引用:

public static void main(String[] args) {

         SoftReference ref = new SoftReference(new MyDate());

         drainMemory(); //  让软引用工作

}

解释:在内存不足时,软引用被终止,等同于:

MyDate date = new MyDate();

 

//------------------- JVM 决定运行 -----------------

If(JVM. 内存不足 ()) {

          date = null;

          System.gc();

}

//-------------------------------------------------------------

3 、弱引用:

public static void main(String[] args) {

         WeakReference ref = new WeakReference(new MyDate());

         System.gc(); //  让弱引用工作

}

解释:在 JVM 垃圾回收运行时,弱引用被终止,等同于:

MyDate date = new MyDate();

 

//------------------ 垃圾回收运行 ------------------

public void WeakSystem.gc() {

          date = null;

          System.gc();

}

4 、假象引用:

public static void main(String[] args) {

         ReferenceQueue queue = new ReferenceQueue();

         PhantomReference ref = new PhantomReference(new MyDate(), queue);

         System.gc(); //  让假象引用工作

}

解释:假象引用,在实例化后,就被终止了,等同于:

MyDate date = new MyDate();

date = null;

 

//------- 终止点,在实例化后,不是在 gc 时,也不是在内存不足时 --------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值