加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

Java强引用、软引用、弱引用、虚引用详解

发布时间:2020-12-13 21:19:44 所属栏目:PHP教程 来源:网络整理
导读:学习Java的同学注意了!!! 学习进程中遇到甚么问题或想获得学习资源的话,欢迎加入Java学习交换群,群号码: 183993990 我们1起学Java! Java中没有指针的概念,而援用就是1个弱化的指针,保证开发不能任意操作内存。最近整理了1下之前不明白的各种级别援

学习Java的同学注意了!!! 
学习进程中遇到甚么问题或想获得学习资源的话,欢迎加入Java学习交换群,群号码:183993990  我们1起学Java!


Java中没有指针的概念,而援用就是1个弱化的指针,保证开发不能任意操作内存。最近整理了1下之前不明白的各种级别援用:强援用、软援用、弱援用、虚援用,它们的特点和利用场景汇总以下: 
1、强援用 
如果1个对象具有强援用,GC绝不会回收它;当内存空间不足,JVM宁愿抛出OutOfMemoryError毛病。1般new出来的对象都是强援用,以下

//强援用 
User strangeReference=new User();  
  • 1
  • 2
  • 1
  • 2

2、软援用 
如果1个对象具有软援用,当内存空间不足,GC会回收这些对象的内存,使用软援用构建敏感数据的缓存。 
在JVM中,软援用是以下定义的,可以通过1个时间戳来回收,下面引自JVM:

    public class SoftReference<T> extends Reference<T> {

    /**
     * Timestamp clock,updated by the garbage collector
     */
    static private long clock;

    /**
     * Timestamp updated by each invocation of the get method.  The VM may use
     * this field when selecting soft references to be cleared,but it is not
     * required to do so.
     */
    private long timestamp;

    /**
     * Creates a new soft reference that refers to the given object.  The new
     * reference is not registered with any queue.
     *
     * @param referent object the new soft reference will refer to
     */
    public SoftReference(T referent) {
        super(referent);
        this.timestamp = clock;
    }

    /**
     * Creates a new soft reference that refers to the given object and is
     * registered with the given queue.
     *
     * @param referent object the new soft reference will refer to
     * @param q the queue with which the reference is to be registered,*          or <tt>null</tt> if registration is not required
     *
     */
    public SoftReference(T referent,ReferenceQueue<? super T> q) {
        super(referent,q);
        /**
     * Returns this reference object's referent.  If this reference object has
     * been cleared,either by the program or by the garbage collector,then
     * this method returns <code>null</code>.
     *
     * @return   The object to which this reference refers,or
     *           <code>null</code> if this reference object has been cleared
     */
    public T get() {
        T o = super.get();
        if (o != null && this.timestamp != clock)
            this.timestamp = clock;
        return o;
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56

软援用的声明的借助强援用或匿名对象,使用泛型SoftReference;可以通过get方法取得强援用。具体以下:

//软援用
SoftReference<User>softReference=new SoftReference<User>(new User());
strangeReference=softReference.get();//通过get方法取得强援用
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

3、弱援用 
如果1个对象具有弱援用,在GC线程扫描内存区域的进程中,不管当前内存空间足够与否,都会回收内存,使用弱援用 构建非敏感数据的缓存。 
在JVM中,弱援用是以下定义的,下面引自JVM:

public WeakReference</**
     * Creates a new weak reference that refers to the given object.  The new
     * reference is not registered with any queue.
     *
     * @param referent object the new weak reference will refer to
     */
    public WeakReference(T referent) {
        super(referent);
    }

    /**
     * Creates a new weak reference that refers to the given object and is
     * registered with the given queue.
     *
     * @param referent object the new weak reference will refer to
     * 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    弱援用的声明的借助强援用或匿名对象,使用泛型WeakReference<T>,具体以下:
    
    //弱援用
    WeakReference<User>weakReference=new WeakReference<User>(new User());
      4、虚援用 
      如果1个对象仅持有虚援用,在任什么时候候都可能被垃圾回收,虚援用与软援用和弱援用的1个区分在于:虚援用必须和援用队列联合使用,虚援用主要用来跟踪对象 被垃圾回收的活动。 
      在JVM中,虚援用是以下定义的,下面引自JVM:

          public class PhantomReference<T> extends Reference<T> {
      
          /**
           * Returns this reference object's referent.  Because the referent of a
           * phantom reference is always inaccessible,this method always returns
           * <code>null</code>.
           *
           * @return  <code>null</code>
           */
          public T get() {
              return null;
          }
      
          /**
           * Creates a new phantom that refers to the given object and
           * is registered with given queue.
           *
           * <p> It is possible to create a phantom with a <tt>null</tt>
           * queue,but such a reference is completely useless: Its <tt>get</tt>
           * method will always return null and,136); box-sizing: border-box;">since it does not have a queue,136); box-sizing: border-box;">it
           * will never be enqueued.
           *
           * @param referent the object the new phantom reference will refer to
           * @param q the queue with which is to be registered,*          or <tt>null</tt> if registration not required
           */
          public PhantomReference(T referent,ReferenceQueue<? super T> q) {
              super(referent,238);">
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    虚援用PhantomReference<T>的声明的借助强援用或匿名对象,结合泛型ReferenceQueue<T>初始化,具体以下:
    
    //虚援用
    PhantomReference<User> phantomReference=new PhantomReference<User>(new User(),136); box-sizing: border-box;">new ReferenceQueue<User>());
      5、总结 
      下面是1段关于强援用、软援用、弱援用、虚援用的程序:

      import java.lang.ref.*;
      import java.util.HashSet;
      import java.util.Set;
      
      class User {
      
          private String name;
      
          public User()
          {}
      
          public User(String name)
          {
              this.name=name;
          }
      
          @Override
          public String toString() {
              return name;
          }
      
          public void finalize(){
              System.out.println("Finalizing ... "+name);
          }
      }
      
      /**
       * Created by jinxu on 15⑷⑵5.
       */
      class ReferenceDemo {
      
          private static ReferenceQueue<User> referenceQueue = new ReferenceQueue<User>();
          static final int size = 10;
      
          static void checkQueue(){
             /* Reference<? extends User> reference = null;
              while((reference = referenceQueue.poll())!=null){
                  System.out.println("In queue : "+reference.get());
              }*/
              Reference<? extends User> reference = referenceQueue.poll();
              if(reference!=null){
                  System."In queue : "+reference.get());
              }
          }
      
          void testSoftReference()
          {
              Set<SoftReference<User>> softReferenceSet = new HashSet<SoftReference<User>>();
              for (int i = 0; i < size; i++) {
                  SoftReference<User> ref = new User("Soft " + i),referenceQueue);
                  System."Just created: " + ref.get());
                  softReferenceSet.add(ref);
              }
              System.gc();
              checkQueue();
          }
      
          void testWeaKReference()
          {
              Set<WeakReference<User>> weakReferenceSet = new HashSet<WeakReference<User>>();
              0; i < size; i++) {
                  WeakReference<User> "Weak " + i),136); box-sizing: border-box;">get());
                  weakReferenceSet.add(void testPhantomReference()
          {
              Set<PhantomReference<User>> phantomReferenceSet = new HashSet<PhantomReference<User>>();
              0; i < size; i++) {
                  PhantomReference<User> ref =
                          "Phantom " + i),136); box-sizing: border-box;">get());
                  phantomReferenceSet.add(void main(String[] args) {
              testSoftReference();
              testWeaKReference();
              testPhantomReference();
          }
      }
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
      • 68
      • 69
      • 70
      • 71
      • 72
      • 73
      • 74
      • 75
      • 76
      • 77
      • 78
      • 79
      • 80
      • 81
      • 82
      • 83
      • 84
      • 85
      • 86
      • 87
      • 88
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
      • 68
      • 69
      • 70
      • 71
      • 72
      • 73
      • 74
      • 75
      • 76
      • 77
      • 78
      • 79
      • 80
      • 81
      • 82
      • 83

      (编辑:李大同)

      【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

      推荐文章
        热点阅读