1. (StrongReference)


Strong references are the most commonly used references. If an object has a strong reference, then the garbage collector will never reclaim it. Below:

    Object strongReference = new Object();


When memory space is low, the Java virtual machine would rather throw a OutOfMemoryError error and terminate the program abnormally, rather than reclaiming objects with strong references at will to solve the memory shortage problem. If a strongly referenced object is not in use, it needs to be weakened so that GC can be reclaimed, as follows:

    strongReference = null;


By explicitly setting the strongReference object to null , or by making it out of the object’s lifecycle scope, gc assumes that no reference exists to the object, and the object can then be reclaimed. Exactly when it is collected depends on the GC algorithm.

    public void test() {
        Object strongReference = new Object();
        
    }


Inside a method there is a strong reference which is stored in the Java stack, while the real content of the reference ( Object ) is stored in the Java heap. When this method finishes running, it exits the method stack, then the reference object has a reference count of 0 and this object is recycled.


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

 ArrayList’s Clear method:


A elementData array is defined in the ArrayList class, and each array element is assigned the value null when the clear method is called to empty the array. Unlike elementData=null , strong references still exist, avoiding memory reallocation when subsequent methods such as add() are called to add elements. It is particularly useful to free memory using reference types stored in memory arrays such as the clear() method, so that memory can be freed in a timely manner.

2.  (SoftReference)


If an object has only soft references, the garbage collector does not reclaim it when there is enough memory space; it reclaims memory for these objects if there is not enough memory space left. 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 caching.

 
    String strongReference = new String("abc");
 
    String str = new String("abc");
    SoftReference<String> softReference = new SoftReference<String>(str);


Soft references can be used in conjunction with a reference queue ( ReferenceQueue ). If the object referenced by a soft reference is garbage collected, the JAVA virtual machine adds the soft reference to the reference queue associated with it.

    ReferenceQueue<String> referenceQueue = new ReferenceQueue<>();
    String str = new String("abc");
    SoftReference<String> softReference = new SoftReference<>(str, referenceQueue);

    str = null;
    // Notify GC
    System.gc();

    System.out.println(softReference.get()); // abc

    Reference<? extends String> reference = referenceQueue.poll();
    System.out.println(reference); //null


Note: soft reference object is in the jvm memory is not enough time will be recycled, we call System.gc () method just to play a role in the notification, the JVM when the JVM scanning recycling object is the JVM’s own state of the decision. Even if you scan a soft reference object, it will not necessarily be recycled, only when there is not enough memory will be recycled.


When out of memory, JVM first sets the object reference in the soft reference to null and then notifies the garbage collector to reclaim it:

    if(JV) {
 
        str = null;
 
        System.gc();
    }


That is, the garbage collection thread will reclaim soft references before the VM throws OutOfMemoryError , and the VM will prioritize the reclamation of soft references that have been idle for a long period of time whenever possible. The “newer” soft objects that have just been built or used** are kept by the VM as long as possible**, which is why the reference queue ReferenceQueue was introduced.

 Application Scenarios:


Browser’s back button. When you press back, is the content of the page displayed during this backward step re-requested or is it taken from the cache? This depends on the specific implementation strategy.


  1. If a web page is content recycled at the end of a browse, it needs to be reconstructed when pressing back to view the previously viewed page;

  2. Storing browsed web pages into memory can result in a lot of wasted memory or even a memory overflow.


This is where soft references can be used, which is a good solution to a practical problem:

 
    Browser browser = new Browser();
 
    BrowserPage page = browser.getPage();
 
    SoftReference softReference = new SoftReference(page);

 
    if(softReference.get() != null) {
 
        page = softReference.get();
    } else {
 
        page = browser.getPage();
 
        softReference = new SoftReference(page);
    }

  3. Weak reference (WeakReference)


The difference between weak references and soft references is that objects with only weak references have a much shorter life cycle. As the garbage collector thread scans the memory area under its jurisdiction, it will reclaim memory for objects with only weak references as soon as it finds them, regardless of whether there is enough space in the current memory. However, since the garbage collector is a low priority thread, it does not always find objects that have only weak references quickly.

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


JVM First set the object reference in the soft reference to null and then notify the garbage collector to recycle it:

    str = null;
    System.gc();


Note: If an object is used occasionally (rarely) and you want it to be readily available 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 a weak reference a strong reference again:

    String str = new String("abc");
    WeakReference<String> weakReference = new WeakReference<>(str);
 
    String strongReference = weakReference.get();


Similarly, a weak reference can be used in conjunction with a reference queue ( ReferenceQueue ), and if the object referenced by the weak reference is garbage collected, the Java virtual machine adds the weak reference to the reference queue associated with it.

 Simple test:

GCTarget.java

public class GCTarget {
 
    public String id;
 
    byte[] buffer = new byte[1024];

    public GCTarget(String id) {
        this.id = id;
    }

    protected void finalize() throws Throwable {
 
        System.out.println("Finalizing GCTarget, id is : " + id);
    }
}

GCTargetWeakReference.java

public class GCTargetWeakReference extends WeakReference<GCTarget> {
 
    public String id;

    public GCTargetWeakReference(GCTarget gcTarget,
              ReferenceQueue<? super GCTarget> queue) {
        super(gcTarget, queue);
        this.id = gcTarget.id;
    }

    protected void finalize() {
        System.out.println("Finalizing GCTargetWeakReference " + id);
    }
}

WeakReferenceTest.java

public class WeakReferenceTest {
 
    private final static ReferenceQueue<GCTarget> REFERENCE_QUEUE = new ReferenceQueue<>();

    public static void main(String[] args) {
        LinkedList<GCTargetWeakReference> gcTargetList = new LinkedList<>();
 
        for (int i = 0; i < 5; i++) {
            GCTarget gcTarget = new GCTarget(String.valueOf(i));
            GCTargetWeakReference weakReference = new GCTargetWeakReference(gcTarget,
                REFERENCE_QUEUE);
            gcTargetList.add(weakReference);

            System.out.println("Just created GCTargetWeakReference obj: " +
                gcTargetList.getLast());
        }

 
        System.gc();

        try {
 
            Thread.sleep(6000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

 
        Reference<? extends GCTarget> reference;
        while((reference = REFERENCE_QUEUE.poll()) != null) {
            if(reference instanceof GCTargetWeakReference) {
                System.out.println("In queue, id is: " +
                    ((GCTargetWeakReference) (reference)).id);
            }
        }
    }
}

 Run WeakReferenceTest.java with the following results:


As you can see WeakReference the life cycle of an object is basically determined by the garbage collector, once the garbage collection thread finds a weakly referenced object, it will be recycled during the next GC process.


4. Phantom Reference


Dummy references are, as the name suggests, virtual. Unlike all other kinds of references, dummy references do not determine the life cycle of an object. If an object holds only dummy references, it is just as likely to be reclaimed by the garbage collector at any time as if it had no references at all.

 Application Scenarios:


Dummy references are primarily used to track the activity of objects being recycled by the garbage collector. One difference between dummy references and soft and weak references is:


A dummy reference must be used in conjunction with a ReferenceQueue. When the garbage collector prepares to reclaim an object, if it finds that it still has a dummy reference, it will add the dummy reference to the reference queue associated with it before reclaiming the object’s memory.

    String str = new String("abc");
    ReferenceQueue queue = new ReferenceQueue();
 
    PhantomReference pr = new PhantomReference(str, queue);


A program can find out if a referenced object is about to be garbage collected by determining whether a dummy reference has been added to the reference queue. If the program finds that a dummy reference has been added to the reference queue, it can take the necessary action before the memory of the referenced object is reclaimed.


By lzz

Leave a Reply

Your email address will not be published. Required fields are marked *