Java's strong reference, weak reference, soft reference, virtual reference

Reprinted from: https://www.cnblogs.com/gudi/p/6403953.html

1. Strong Reference

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

Object o=new Object(); // strong reference

       When the memory space is insufficient, the Java virtual machine would rather throw an OutOfMemoryError error to cause the program to terminate abnormally, rather than solve the problem of insufficient memory by arbitrarily reclaiming objects with strong references. If not used, weaken the reference in the following ways, as follows:

o=null; // help the garbage collector to recycle this object

       Explicitly setting o to null, or beyond the scope of the object's life cycle, the gc thinks that there is no reference to the object, and the object can be recycled. When to collect it depends on the gc's algorithm.

Example:

public void test(){
    Object o=new Object();
    // omit other operations
}

       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 the method is completed, it will exit the method stack, the reference to the reference 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 are very useful in practice. For example, the implementation source code of ArrayList:

copy code
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;
}
copy code

       A private variable elementData array is defined in the ArrayList class. When calling the method to clear the array, you can see that each array content is assigned null. Unlike elementData=null, the strong reference still exists, avoiding reallocation of memory when elements are added by subsequent calls to add() and other methods. Using methods such as clear() to release memory is especially suitable for reference types stored in arrays, so that memory can be released in time. 

2. Soft Reference

      If an object has only soft references, the memory space is sufficient, and the garbage collector will not reclaim it; if the memory space is insufficient, the memory of these objects will be reclaimed. The object can be used by the program as long as it is not collected by the garbage collector. Soft references can be used to implement memory-sensitive caches.      

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

When out of memory, it is equivalent to:    

If(JVM.Out of memory()) {
   str = null; // convert to soft reference
   System.gc(); // Garbage collector for collection
}

  Soft references have important applications in practice, such as the browser's back button. When you press back, is the content of the web page displayed when back is re-requested or retrieved from the cache? It depends on the specific implementation strategy.

(1) If a web page recycles its content at the end of browsing, it needs to be rebuilt when you press Back to view the previously browsed page.

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

You can use soft references

copy code
Browser prev = new Browser(); // Get the page to browse
SoftReference sr = new SoftReference(prev); // Set as soft reference after browsing        
if(sr.get()!=null){
    rev = (Browser) sr.get(); // It has not been recycled by the collector, get it directly
}else{
    prev = new Browser(); // Due to tight memory, the soft referenced object is reclaimed
    sr = new SoftReference(prev); // rebuild
}
copy code

      This is a good solution to the actual problem.

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

3. Weak Reference (WeakReference)

      The difference between weak references and soft references is that objects with only weak references have a shorter lifetime. In the process of scanning the memory area under the jurisdiction of the garbage collector thread, once an object with only weak references is found, its memory will be reclaimed regardless of whether the current memory space is sufficient or not. However, since the garbage collector is a very low-priority thread, objects that only have weak references will not necessarily be discovered 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 the object is used occasionally, and you want to be able to get it whenever you use it, but you don't want to affect the garbage collection of the object, you should use a Weak Reference to remember this object.   

   The following code will make str a strong reference again:    

String  abc = abcWeakRef.get();

    Weak references 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 associated reference queue.

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

   This reference does not have any additional effect on the garbage collection decision of the object

copy code
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 { // rest for a few minutes below, let the above garbage collection thread run to completion
            Thread.currentThread().sleep(6000);
        } catch (InterruptedException e) {
            e.printStackTrace ();
        }
        checkQueue();
    }
}

class VeryBig {
    public String id;
    // Take up space and let the thread recycle
    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);
    }
}
copy code

The final output is:

copy code
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
copy code

4. PhantomReference

    "Virtual reference", as the name suggests, is just in name only. Unlike other references, virtual reference does not determine the life cycle of an object. If an object only holds phantom references, then it can be collected by the garbage collector at any time as if it had no references at all.

    Phantom references are primarily used to track the activity of objects being reclaimed by the garbage collector. One difference between virtual references and soft references and weak references is that virtual references must be used in conjunction with reference queues. When the garbage collector is ready to reclaim an object, if it finds that it still has a virtual reference, it will add the virtual reference to the reference queue associated with it before reclaiming the memory of the object.

5. Summary

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

    Strong References > Soft References > Weak References > Phantom References

    Let's take a look at the difference between them in garbage collection through the figure:

     

       When the garbage collector collects, some objects are collected and some are not. 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 don't know much about this, you can refer to the following articles:

      Explain with the form, as follows:

      

     references:

    1、http://www.cnblogs.com/skywang12345/p/3154474.html

    2、http://blog.csdn.net/lifetragedy?viewmode=contents

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325126478&siteId=291194637