Four types of references in Java, strong references, weak references, soft references, and phantom references

After JDK1.2, object references are divided into four states, namely strong references, soft references, weak references and virtual references. In this way, you can control the life cycle of the object more flexibly.

1. Strong Reference (StrongReference)

      Strong citations are the most commonly used citations. If an object has a strong reference, the garbage collector will never reclaim it . as follows:

Object o=new Object();   //  强引用

      When the memory space is insufficient, the Java virtual machine would rather throw an OutOfMemoryError error to make the program terminate abnormally, and would not solve the problem of insufficient memory by reclaiming objects with strong references at will. If not, use the following methods to weaken the reference, as follows:

o=null;     // 帮助垃圾收集器回收此对象

      Explicitly set o to null, or beyond the scope of the life cycle of the object, gc thinks that the object does not have a reference, then the object can be recycled. When to collect it depends on the algorithm of gc.

For example:

    public void test(){
        Object o=new Object();
        // 省略其他操作
    }

There is a strong reference inside a method, this reference is stored in the stack, and the real reference content (Object) is stored in the heap. When this method finishes running, it will exit the method stack, and the reference to the content does not exist, and the Object will be recycled.

But if this o is a global variable, it needs to be assigned to null when the object is not used, because strong references will not be garbage collected.

Strong references have very important uses in practice, for example, the implementation source code of ArrayList:

 private transient Object[] elementData;
    public void clear() {
            modCount++;
            // Let gc do its work
            for (int i = 0; i < size; i++)
                elementData[i] = null;
            size = 0;
    }

A private variable elementData array is defined in the ArrayList class. When calling the method to clear the array, you can see that the content of each array is assigned a value of null. Different from elementData=null, the strong reference still exists, avoiding re-allocation of memory when adding elements in subsequent calls to add() and other methods. Using methods such as the clear() method to release memory is particularly applicable to the reference types stored in the array, so that the memory can be released in time.


2. Soft Reference (SoftReference)

        If an object has only soft references, the memory space is sufficient, the garbage collector will not reclaim it; if the memory space is insufficient, the memory of these objects will be reclaimed . As long as the garbage collector does not reclaim it, the object can be used by the program. Soft references can be used to implement memory-sensitive caches ( mybatis SoftCache uses weak references, and the Map in ThreadLocal also uses soft references [to prevent memory leaks] ).  

Soft reference declaration format:

import java.lang.ref.SoftReference;
 
public class TestRef {
    public static void main(String args[]) {
        SoftReference<String> str = new SoftReference<String>(new String("abc"));
        System.out.println(str.get());
        //通知JVM进行内存回收
        System.gc();
        System.out.println(str.get());
    }
}

    Output result:

It can be seen that the JVM has sufficient memory at this time , and objects associated with soft references have not yet been reclaimed .

 

 String str=new String("abc");                                     // 强引用
 SoftReference<String> softRef=new SoftReference<String>(str);     // 软引用  

When the memory is insufficient, it is equivalent to:

    If(JVM.内存不足()) {
       str = null;  // 转换为软引用
       System.gc(); // 垃圾回收器进行回收
    }

Soft references have important applications in practice, such as the back button of a browser. When pressing back, should the content of the web page displayed during the backing be requested again or fetched from the cache? It depends on the specific implementation strategy.

(1) If a webpage is recycled at the end of browsing, it needs to be rebuilt when you press Back to view the previously browsed page

(2) If you store the browsed web pages in the memory, it will cause a lot of waste of memory, and even cause memory overflow

At this time, you can use soft references

    Browser prev = new Browser();               // 获取页面进行浏览
    SoftReference sr = new SoftReference(prev); // 浏览完毕后置为软引用        
    if(sr.get()!=null){
        rev = (Browser) sr.get();           // 还没有被回收器回收,直接获取
    }else{
        prev = new Browser();               // 由于内存吃紧,所以对软引用的对象回收了
        sr = new SoftReference(prev);       // 重新构建
    }

This solves the actual problem very well.

       A soft reference can be used in conjunction with a reference queue (ReferenceQueue). If the object referenced by the soft reference is recycled by the garbage collector, the Java virtual machine will add the soft reference to the reference queue associated with it.


3. Weak Reference (WeakReference)

      The difference between weak references and soft references is that only objects with weak references have a shorter life cycle. In the process of the garbage collector thread scanning the memory area under its jurisdiction, once an object with only weak references is found, its memory will be reclaimed regardless of whether the current memory space is sufficient . However, because the garbage collector is a low-priority thread, objects that only have weak references may not be found quickly.

  String str=new String("abc");    
  WeakReference<String> abcWeakRef = new WeakReference<String>(str);
  str=null;  

When the garbage collector scans and collects, it is equivalent to:

    str = null;
    System.gc();

   If this object is used occasionally and you want to get it at any time when you use it, but you don't want to affect the garbage collection of this object, then you should use Weak Reference to remember this object.   

   The following code will make str again a strong reference:

String  abc = abcWeakRef.get();

A weak reference can be used in conjunction with a reference queue (ReferenceQueue). If the object referenced by the weak reference is garbage collected, the Java virtual machine will add the weak reference to the reference queue associated with it.

When you want to refer to an object, but this object has its own life cycle, and you don't want to intervene in the life cycle of this object, then you use weak references.

This reference will not have any additional influence on the garbage collection judgment of the object.

    public class ReferenceTest {
     
        private static ReferenceQueue<VeryBig> rq = new ReferenceQueue<VeryBig>();
     
        public static void checkQueue() {
            Reference<? extends VeryBig> ref = null;
            while ((ref = rq.poll()) != null) {
                if (ref != null) {
                    System.out.println("In queue: "    + ((VeryBigWeakReference) (ref)).id);
                }
            }
        }
     
        public static void main(String args[]) {
            int size = 3;
            LinkedList<WeakReference<VeryBig>> weakList = new LinkedList<WeakReference<VeryBig>>();
            for (int i = 0; i < size; i++) {
                weakList.add(new VeryBigWeakReference(new VeryBig("Weak " + i), rq));
                System.out.println("Just created weak: " + weakList.getLast());
     
            }
     
            System.gc();
            try { // 下面休息几分钟,让上面的垃圾回收线程运行完成
                Thread.currentThread().sleep(6000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            checkQueue();
        }
    }
     
    class VeryBig {
        public String id;
        // 占用空间,让线程进行回收
        byte[] b = new byte[2 * 1024];
     
        public VeryBig(String id) {
            this.id = id;
        }
     
        protected void finalize() {
            System.out.println("Finalizing VeryBig " + id);
        }
    }
     
    class VeryBigWeakReference extends WeakReference<VeryBig> {
        public String id;
     
        public VeryBigWeakReference(VeryBig big, ReferenceQueue<VeryBig> rq) {
            super(big, rq);
            this.id = big.id;
        }
     
        protected void finalize() {
            System.out.println("Finalizing VeryBigWeakReference " + id);
        }
    }

The final output is:

    Just created weak: com.javabase.reference.VeryBigWeakReference@1641c0
    Just created weak: com.javabase.reference.VeryBigWeakReference@136ab79
    Just created weak: com.javabase.reference.VeryBigWeakReference@33c1aa
    Finalizing VeryBig Weak 2
    Finalizing VeryBig Weak 1
    Finalizing VeryBig Weak 0
    In queue: Weak 1
    In queue: Weak 2
    In queue: Weak 0


4. Phantom Reference (PhantomReference)

     As the name implies, "virtual reference" is nothing but a virtual reference. Unlike other types of references, a virtual reference does not determine the life cycle of an object. If an object holds only phantom references, then it is the same as without any references, and may be collected by the garbage collector at any time.

    Phantom references are mainly used to track the activities of objects being recycled by the garbage collector. One difference between virtual reference and soft reference and weak reference is that virtual reference must be used in conjunction with reference queue (ReferenceQueue). When the garbage collector is about to reclaim an object, if it finds that it has a phantom reference, it will add the phantom reference to the reference queue associated with it before reclaiming the object's memory.

 

5. Summary

 The levels of Java 4 references from high to low are:

             Strong Reference> Soft Reference> Weak Reference> Phantom Reference

Look at the difference between them in garbage collection through the diagram:


When the garbage collector collects, some objects will be collected, and some will not be collected. The garbage collector will mark the surviving objects from the root object Object, and then recycle some unreachable objects and some referenced objects. If you are not familiar with this, you can refer to the following article:

Portal: Java memory management http://blog.csdn.net/mazhimazh/article/category/1907599

Explain it through the table, as follows:

Reference type Garbage collection time use Survival time
Strong citation Never General state of the object Terminate when the JVM stops running
Soft reference When memory is low Object cache Terminate when memory is insufficient
Weak reference During garbage collection Object cache Terminate after gc runs
Phantom reference Unknown Unknown Unknown

 

 

 

 

 

 

Reference article:

https://blog.csdn.net/mazhimazh/article/details/19752475

https://blog.csdn.net/qq_33591903/article/details/82024257

Guess you like

Origin blog.csdn.net/qianzhitu/article/details/103103667