zoukankan      html  css  js  c++  java
  • 强引用,软引用,弱引用与虚引用

    强引用:(StrongReference)

    强引用指普通的对象引用

    例如:

    StringBuffer str = new StringBuffer("hello world");

    局部变量str会被放到栈里,而StringBuffer实例对象会被放在堆内,局部变量str指向堆内的StringBuffer对象,通过str可以操作该对象,那么str就是StringBuffer的强引用

    StringBuffer str1 = str;

    当发生了这条语句,则

     此时这两个引用都是强引用

    强引用具备如下特点:

      1、通过强引用可以直接访问目标对象

      2、强引用所指向的对象在任何时候都不会被系统回收,虚拟机宁愿抛出OOM(内存溢出)异常,也不会回收强引用所指向的对象

      3、强引用可能导致内存泄漏(站着空间不释放,积累的多了内存泄漏会导致内存溢出)

    软引用:(SoftReference)

    软引用描述一些还有用但非必需的对象,用java.lang.ref.SoftReference类表示对于软引用关联的对象GC未必会一定会收,只有当内存资源紧张时,软引用对象才会被回收,所以软引用对象不会引起内存溢出(OOM)

     1 import java.lang.ref.SoftReference;
     2 
     3 //软引用问题
     4 public class SoftRef {
     5     public static class User{
     6         public int id;
     7         public String name;
     8         public User(int id,String name) {
     9             this.id = id;
    10             this.name = name;
    11         }
    12         @Override
    13         public String toString() {
    14             return "User [id=" + id + ", name=" + name + "]";
    15         }
    16         
    17         
    18     }
    19     
    20     public static void main(String[] args) {
    21         User u = new User(1,"吉米");
    22         //从强引用中获取软引用
    23         SoftReference<User> sr = new SoftReference<User>(u);
    24         //将强引用去除
    25         u = null;
    26         // get方法返回此引用对象的指示对象。用来获取与软引用关联的对象的引用
    27         System.out.println(sr.get());
    28         System.out.println("After GC");
    29         System.gc();
    30         System.out.println(sr.get());
    31         
    32         
    33         //这样测试出来,软引用可能不会被gc回收,此时需要模拟一下内存很紧张的状态
    34         byte b[] = new byte[1024*925*77];
    35         System.gc();
    36         System.out.println(sr.get());
    37         
    38     }
    39 }
    输出:在-Xmx10m下输出
    User [id=1, name=吉米] //第一次从软引用中获取数据 After GC User [id=1, name=吉米] //GC没有清除软引用 null //由于内存紧张,软引用被GC清理

    此外,软引用还可以附带一个引用队列,当对象可达性发生改时(由可达变为不可达,被回收),此时软引用进入队列,通过这个引用队列,可以跟踪对象的回收情况 

    弱引用:(WeakReference)

    弱引用是比软引用还弱的引用,在系统进行GC 时,只要发现弱引用,不管系统的堆空间是用了一点还是用了一大半,都会回收弱引用的对象。但是通常GC线程的优先级较低,因此不能立即发现持有弱引用的对象,在这种情况下弱引用对象可以存在较长的时间,一旦弱引用对象被回收,弱引用对象会加到一个注册的引用队列中去

     

     弱引用代码:

     1 import java.lang.ref.WeakReference;
     2 
     3 //弱引用
     4 public class WeakRef {
     5     public static class User{
     6         public int id;
     7         public String name;
     8         public User(int id, String name) {
     9             this.id = id;
    10             this.name = name;
    11         }
    12         @Override
    13         public String toString() {
    14             return "[id=" + id + ", name=" + name + "]";
    15         }
    16         
    17     }
    18     
    19     public static void main(String[] args) {
    20         User u = new User(1,"geym");
    21         //创建软引用对象
    22         WeakReference<User> wr = new WeakReference<User>(u);
    23         System.out.println(wr.get());
    24         System.gc();
    25         System.out.println("After GC:");
    26         System.out.println(wr.get());
    27     }
    28 }

    输出:

    [id=1, name=geym]
    After GC:
    null

    根据软引用和弱引用的特性,非常适合保存一些可有可无的缓存,如果这么做,当系统内存空间不足时,会及时回收他们,不会导致内存溢出,当系统内存资源充足时,这些还存有可以存在相当长的时间,提升系统速度。

    虚引用:(PhantomReference)(对象回收和跟踪)

    虚引用是所有引用中最弱的一个持有一个虚引用的对象,和没有引用一样,随时都有可能会被垃圾回收器回收,当用虚引用的get方法去尝试获得强引用对象时总是会失败,并且他必须和引用队列一起使用,用于跟踪垃圾回收过程,当垃圾回收器回收一个持有虚引用的对象时,在回收对象后,将这个虚引用对象加入到引用队列中,用来通知应用程序垃圾的回收情况。

    虚引用代码:

     1 import java.lang.ref.PhantomReference;
     2 import java.lang.ref.ReferenceQueue;
     3 
     4 public class PlantomRef {
     5     public static class User{
     6         public int id;
     7         public String name;
     8         public User(int id,String name){
     9             this.id = id;
    10             this.name = name;
    11         }
    12         @Override
    13         public String toString() {
    14             return "User [id=" + id + ", name=" + name + "]";
    15         }
    16         
    17     }
    18     
    19     public static void main(String[] args) {
    20         User u = new User(1,"吉米");
    21         ReferenceQueue<? super User> queue = new ReferenceQueue<User>();
    22         PhantomReference<User> pr = new PhantomReference<User>(u,queue);
    23         System.out.println(pr.get());
    24         
    25     }
    26     
    27     
    28     
    29 }

    输出为null

    由于虚引用可以跟踪对象的回收时间,所以可以将一些资源的释放操作放置在虚引用中执行和记录

  • 相关阅读:
    drupal中安装CKEditor文本编辑器,并配置图片上传功能 之 方法二
    drupal 开发笔记
    CSS选择器:子选择符号
    转:Redis和Memcache的区别分析
    转:php 获取memcache所有key
    Fatal error: Namespace declaration statement has to be the very first statement or after any declare call in the script in
    drupal7 boost模块为登录用户提供缓存
    转:drupal使用superfish建立下拉菜单
    RAID详解[RAID0/RAID1/RAID10/RAID5]
    DataV纪录
  • 原文地址:https://www.cnblogs.com/rgever/p/8902210.html
Copyright © 2011-2022 走看看