JVM Basics - strong reference_ Soft reference_ Weak reference_ Virtual reference

Posted by Deserteye on Thu, 20 Jan 2022 01:19:00 +0100

I Strong reference

  • When the memory is insufficient, the JVM starts garbage collection. For strongly referenced objects, even if there is OOM, the object will not be recycled, and it will not be recycled ~!

  • Strong reference is our most common common object reference. As long as there is a strong reference pointing to an object, it can indicate that the object is still "alive", and the garbage collector will not touch this object.

  • The most common in Java is strong reference. Assigning an object to a reference variable is a strong reference.

  • When an object is referenced by a strongly referenced variable, it is in reachable state. It cannot be recycled by the garbage collection mechanism. Even if the object will never be used in the future, the JVM will not recycle it. Therefore, strong reference is one of the main reasons for Java memory leakage.

  • For an ordinary object, if there is no other reference relationship, as long as the corresponding (strong) reference is assigned null beyond the action of the reference or explicitly, it can be considered as garbage collection (of course, the specific collection time depends on the garbage collection strategy)

package com.xizi.Jvm;

public class StrongReferenceDemo {

    public static void main(String[] args) {
        // The default defined in this way is strong application
        Object obj1 = new Object();
        // Use the second reference to point to the Object you just created
        Object obj2 = obj1;
        // Empty
        obj1 = null;
        // garbage collection
        System.gc();
        System.out.println(obj1);
        System.out.println(obj2);
    }
}

  • The output result is that we can find that even if obj1 is set to null, then gc is called for recovery, but no object is recovered, obj2 can still point to the address, that is, garbage collector does not recycle the object.

II Soft reference

①. SoftReference

  • Soft reference is a relatively weak reference, which needs JAVA Implemented by lang.ref.softreference class, objects can be exempted from some garbage collection. For objects with only soft reference:

    • When the system memory is sufficient, it will not be recycled
    • When the system runs out of memory, it is recycled
  • Soft references are usually used in memory sensitive programs. For example, soft references are used in cache. When memory is enough, they are retained and recycled

package com.xizi.Jvm;

import java.lang.ref.SoftReference;

public class SoftReferenceDemo {

    // When there is enough memory
    public static void softRefMemoryEnough() {
        // Create a strong app
        Object o1 = new Object();
        // Create a soft reference
        SoftReference<Object> softReference = new SoftReference<>(o1);
        System.out.println(o1);
        System.out.println(softReference.get());
        o1 = null;
        System.gc(); // Manual GC
        System.out.println(o1);
        System.out.println(softReference.get());
    }

    /**
     * JVM Configuration, deliberately generate large objects and configure small memory to make it run out of memory, resulting in OOM. Look at the recycling of soft references
     * -Xms5m -Xmx5m -XX:+PrintGCDetails
     */
    public static void softRefMemoryNoEnough() {
        System.out.println("========================");
        // Create a strong app
        Object o1 = new Object();
        // Create a soft reference
        SoftReference<Object> softReference = new SoftReference<>(o1);
        System.out.println(o1);
        System.out.println(softReference.get());
        o1 = null;
        // Simulate OOM automatic GC
        try {
            // Create a 30M large object
            byte[] bytes = new byte[30 * 1024 * 1024];
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            System.out.println(o1);
            System.out.println(softReference.get());
        }
    }

    public static void main(String[] args) {
        softRefMemoryEnough();
        softRefMemoryNoEnough();
    }
}

III Weak reference

①. WeakReference

  • After the GC operation, the weakly referenced will be recycled
package com.xizi.Jvm;

import java.lang.ref.WeakReference;

// Weak reference
public class WeakReferenceDemo {
    public static void main(String[] args) {
        Object o1 = new Object();
        WeakReference<Object> weakReference = new WeakReference<>(o1);
        System.out.println(o1);
        System.out.println(weakReference.get());
        o1 = null;
        System.gc();
        System.out.println(o1);
        System.out.println(weakReference.get());
    }
}

②. WeakHashMap

package com.xizi.Jvm;

import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;

public class WeakHashMapDemo {
    public static void main(String[] args) {
        myHashMap();
        System.out.println("==========");
        myWeakHashMap();
    }

    private static void myHashMap() {
        Map<Integer, String> map = new HashMap<>();
        Integer key = new Integer(1);
        String value = "HashMap";
        map.put(key, value);
        System.out.println(map);
        key = null;
        System.gc();
        System.out.println(map);
    }

    private static void myWeakHashMap() {
        Map<Integer, String> map = new WeakHashMap<>();
        Integer key = new Integer(1);
        String value = "WeakHashMap";
        map.put(key, value);
        System.out.println(map);
        key = null;
//        value = null;
        System.gc();
        System.out.println(map);
    }
}

IV Virtual reference

①. PhantomReference

  • Virtual reference, also known as ghost reference, requires Java Lang.ref.phantomreference class
  • As the name suggests, it is virtual. Unlike other references, virtual references do not determine the life cycle of objects.
  • If an object holds a virtual reference, it may be recycled by the garbage collector at any time like it does not have any reference. It cannot be used alone or access the object through it. The virtual reference must be used in conjunction with the reference queue ReferenceQueue.
  • The main function of virtual reference and tracking the garbage collection status of objects is only to provide a mechanism to ensure that objects do something after they are finalize d.
  • The get method of phantom reference always returns null, so the reference object of the object cannot be accessed. Its significance is that an object has entered the finalization stage and can be recycled by gc to realize more flexible recycling operation than the finalization mechanism
  • In other words, the only purpose of setting virtual reference association is to receive a system notification or add further processing when the object is recycled by the collector. Java technology allows the use of the finalize() method to do the necessary cleaning work before the garbage collector clears the object from memory

②. Reference queue

  • Soft references, weak references and virtual references need to be saved in the reference queue before recycling
  • During GC recycling, objects with weak and virtual references will be recycled, but they will be sent to the reference queue before recycling
package com.xizi.Jvm;

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.util.concurrent.TimeUnit;

// The only purpose of setting virtual reference association is to receive a system notification or add further processing when the object is recycled by the collector
public class PhantomReferenceDemo {

    public static void main(String[] args) {
        Object o1 = new Object();
        // Create reference queue
        ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();

        // Create a weak reference
//        WeakReference<Object> weakReference = new WeakReference<>(o1, referenceQueue);

        // Create a virtual reference
        // The get method of phantom reference always returns null,
        PhantomReference<Object> weakReference = new PhantomReference<>(o1, referenceQueue);

        System.out.println(o1); // java.lang.Object@5b2133b1
        System.out.println(weakReference.get()); // null
        // Get the contents of the queue
        System.out.println(referenceQueue.poll()); // null
        System.out.println("======================");
        o1 = null;
        System.gc();
        System.out.println("implement GC operation");
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(o1); // null
        System.out.println(weakReference.get()); // null
        // Get the contents of the queue
        System.out.println(referenceQueue.poll()); // java.lang.ref.PhantomReference@72ea2f77
    }
}


  • From here, we can see that after garbage collection, our weak reference object is also set to null, but the instance of the reference can also be exported in the queue, which shows that before collection, the instance of the weak reference is placed in the reference queue, and we can carry out some post operations through the reference queue

V GCRoots and four references summary

  • The red part is outside the garbage collection, that is, strongly referenced

  • Blue part: it belongs to soft reference. It is only recycled when there is not enough memory

  • Virtual reference and weak reference: each time garbage collection, it will be killed, but it will still exist in the reference queue before it is killed. We can use the reference queue for some notification mechanisms