Java中的4中引用的差别和使用场景

Java中的4中引用的差别和使用场景

一、强引用

  1. 特点

    • 强引用不会被GC回收,当前内存不足的时候,JVM宁愿抛出java.lang.OutOfMemoryError: Java heap space让程序假死,也不会随意去回收具有强引用的对象
    • 常见的强引用:把一个对象赋给引用变量,这个引用变量就是一个强引用,如果在不使用这个变量的时候,将这变量强制为null,可以被gc掉
  2. 代码:

    /**
     * @Author yixiangfeng
     * @ClassName StrongRef
     * @Description 强引用
     * @CreateTime  下午2:34
     **/
    public class StrongRef {
    
        public static class User {
            private Integer userId;
    
            private String userName;
    
            public User(Integer userId,String userName) {
                this.userId = userId;
                this.userName = userName;
            }
    
            @Override
            public String toString() {
                return "User{" +
                        "userId=" + userId +
                        ", userName='" + userName + '\'' +
                        '}';
            }
        }
    
        public static void main(String[] args) {
            User user = new User(1, "zhaoliu");
            User strongUser = user;
            System.out.println("Before GC");
            System.out.println(user);
            user = null;
            System.gc();
            System.out.println("After GC");
            System.out.println(strongUser);
    
        }
    }
    

二、弱引用

  1. 特点:

    • 弱引用需要用WeakReference类来实现。比软引用的生存期更短,对于只有弱引用的对象。只要垃圾回收机制一运行,不管JVM的内存空间是否足够。总会回收该对象占用的内存
    • Weak引用对象常用于Map数据结构中,引用占用内存空间较大的对象
  2. 代码:

    package top.yxf.jvm;
    
    import java.lang.ref.WeakReference;
    
    /**
     * @Author yixiangfeng
     * @ClassName WeakRef
     * @Description 虚引用
     * @CreateTime  下午5:08
     **/
    public class WeakRef {
    
        public static class User {
            private Integer userId;
    
            private String userName;
    
            public User(Integer userId,String userName) {
                this.userId = userId;
                this.userName = userName;
            }
    
            @Override
            public String toString() {
                return "User{" +
                        "userId=" + userId +
                        ", userName='" + userName + '\'' +
                        '}';
            }
        }
    
        public static void main(String[] args) {
            User user = new User(1,"zhangsan");
            WeakReference<User> reference = new WeakReference<>(user);
            user = null;
            System.out.println("Before GC");
            System.out.println(reference.get());
            System.gc();
            System.out.println("After GC");
            System.out.println(reference.get());
        }
        
    }
    
    ## 输出结果
    Before GC
    User{userId=1, userName='zhangsan'}
    After GC
    null
    

三、软引用

  1. 特点

    • 软引用需要用SoftReference类实现。
    • 当系统内存足够时它不会被回收。
  2. 代码:

    /**
     * @Author yixiangfeng
     * @ClassName SoftRef
     * @Description 软引用
     * @CreateTime  上午11:47
     **/
    public class SoftRef {
    
        public static class User {
            private Integer userId;
    
            private String userName;
    
            public User(Integer userId,String userName) {
                this.userId = userId;
                this.userName = userName;
            }
    
            @Override
            public String toString() {
                return "User{" +
                        "userId=" + userId +
                        ", userName='" + userName + '\'' +
                        '}';
            }
        }
        public static void main(String[] args) {
            User lisi = new User(1, "lisi");
            SoftReference<User> softReference = new SoftReference(lisi);
    
            System.out.println("Before gc");
    
            System.out.println(softReference.get());
            lisi = null;
            System.gc();
            System.out.println("After gc");
            System.out.println(softReference.get());
        }
    }
    
    
    ## 输出结果
    Before gc
    User{userId=1, userName='lisi'}
    After gc
    User{userId=1, userName='lisi'}
    

四、虚引用

  1. 特点

    • 虚引用需要PhantomReference类实现,它不能单独使用,必须和引用队列联合使用。
    • 虚引用的主要作用是跟踪对象被垃圾回收的状态。
    • 主要是跟踪对象被垃圾回收的状态
  2. 代码:

    1. PhantomReference源码:
      在这里插入图片描述
      在这里插入图片描述

      从源码可以看出,始终获取的都是null。注释提示: Returns this reference object’s referent. Because the referent of a phantom reference is always inaccessible, this method always returns null (返回此引用对象的引用对象,因为幻想引用的引用对象始终不可访问,所以此方法始终返回的是null)

    2. 实现

      /**
       * @Author yixiangfeng
       * @ClassName PhantomRef
       * @Description 虚引用
       * @CreateTime  上午11:49
       **/
      public class PhantomRef {
      
          public static class User {
              private Integer userId;
      
              private String userName;
      
              public User(Integer userId,String userName) {
                  this.userId = userId;
                  this.userName = userName;
              }
      
              @Override
              public String toString() {
                  return "User{" +
                          "userId=" + userId +
                          ", userName='" + userName + '\'' +
                          '}';
              }
          }
      
          public static void main(String[] args) {
              User wangwu = new User(1, "wangwu");
              ReferenceQueue<User> queue = new ReferenceQueue<>();
              PhantomReference<User> phantomReference = new PhantomReference<>(wangwu,queue);
              System.out.println("Before gc");
              System.out.println(phantomReference.get());
       	    System.out.println(queue.poll());
              wangwu = null;
              System.gc();
              System.out.println("After gc");
              System.out.println(phantomReference.get());
       	    System.out.println(queue.poll());
          }
      }
      
      
      ## 输出结果
      Before gc
      null
      After gc
      null
      
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值