Four reference types of Java

Posted by scnov on Sun, 30 Jan 2022 06:09:06 +0100

There are four levels of references in Java: strong reference, soft reference, weak reference and virtual reference.

 

Strong reference

References in Java are similar to the most difficult pointers in C language. (I'm an introduction to C language programming, and the concept of pointer still goes deep into my heart.) By reference, you can operate on objects in the heap. For example:

StringBuffer stringBuffer = new StringBuffer("Helloword");

The variable STR points to the heap space where the StringBuffer instance is located. This object can be operated through str.

Features of strong reference:

  • Strong references can directly access the target object.

  • The object pointed to by a strong reference will not be recycled by the system at any time. The JVM would rather throw an OOM exception than reclaim the object pointed to by a strong reference.

  • Strong references can cause memory leaks.

 

Soft reference

Soft reference is the strongest reference type besides strong reference. You can use Java Lang.ref.softreference uses soft references. An object with a soft reference will not be recycled by the JVM soon. The JVM will judge when to recycle it according to the current heap usage. When the heap utilization is close to the threshold, soft referenced objects will be recycled. Therefore, soft references can be used to implement memory sensitive caching.

Features of SoftReference: an instance of SoftReference saves a soft reference to a Java object. The existence of the soft reference does not prevent the garbage collection thread from recycling the Java object. That is, once the SoftReference saves the soft reference to a Java object, the get() method provided by the SoftReference class returns the strong reference of the Java object before the garbage thread recycles the Java object. Once the garbage thread recycles the Java object, the get() method returns null.

The following is an example to illustrate the use of soft reference.

Set the parameters - Xmx5m -Xms5m -XX:+PrintGCDetails in your IDE to specify that the heap memory size is 5m.

public class MyObject {
    private byte[] bytes;

    public MyObject() {
        bytes = new byte[1024 * 1024 * 2];
    }

    public static void main(String[] args) {
        MyObject myObject = new MyObject();
        SoftReference sf = new SoftReference<>(myObject);
        // The object maintained by soft reference does not mean that it will be emptied when the memory is insufficient; 
        // Only when the memory is insufficient, if the soft referenced object has no other references, it will be recycled
        // Therefore, you need to empty the referenced myObject object here, and comment out this line and it will not be recycled
        myObject = null;
        System.out.println("Is it recycled" + sf.get());
        // The allocation of 2M memory space leads to the triggering of GC and the recycling of soft reference objects
        byte[] bytes = new byte[1024 * 1024 * 2];
        System.out.println("Is it recycled" + sf.get());
    }
}

Operation results:

Is it recycled com.jaemon.demo.MyObject@2ef9b8bc
 Is it recycled null

Weak reference

A weak reference is a type of reference that is weaker than a soft reference. During system GC, as long as a weak reference is found, the object will be recycled regardless of whether the system heap space is sufficient. In Java, you can use Java Lang.ref.weakreference instance to save a weak reference to a Java object.

public class MyObject {
    public static void main(String[] args) {
        MyObject obj = new MyObject();
        WeakReference sf = new WeakReference(obj);
        // Objects maintained by weak references are not cleared during GC; 
        // Only in GC, if the weakly referenced object has no other references, it will be recycled
        // Therefore, you need to empty the referenced obj object here, and comment out this line and it will not be recycled
        obj = null;
        System.out.println("Is it recycled"+sf.get());
        System.gc();
        System.out.println("Is it recycled"+sf.get());
    }
}

Operation results:

Is it recycled com.jaemon.demo.MyObject@17c68925
 Is it recycled null

Soft reference and weak reference are very suitable for storing those dispensable cache data. If you do so, when the system memory is insufficient, these cache data will be recycled and will not lead to memory overflow. When the memory resources are sufficient, these cached data can exist for a long time, so as to accelerate the system.

 

Virtual reference

Virtual references are the weakest of all types. An object with a virtual reference is almost the same as an object without a reference, and may be recycled by the garbage collector at any time. When trying to get a strong reference through the get() method of a virtual reference, it always fails. Also, virtual references must be used with reference queues to track the garbage collection process.

When the garbage collector prepares to recycle an object, if it finds that it still has a virtual reference, it will destroy the object and add the virtual reference to the reference queue after garbage collection. The program can know whether the referenced object will be garbage collected by judging whether the virtual reference has been added to the reference queue. If the program finds that a virtual reference has been added to the reference queue, it can take the necessary action before the memory of the referenced object is reclaimed.

public class MyObject {
    public static void main(String[] args) {
        MyObject obj = new MyObject();
        ReferenceQueue referenceQueue = new ReferenceQueue<>();
        PhantomReference sf = new PhantomReference<>(obj, referenceQueue);
        obj = null;
        System.out.println("Is it recycled"+sf.get());
        System.gc();
        System.out.println("Is it recycled"+sf.get());
    }
}

Operation results:

Is it recycled null
 Is it recycled null

Several points to note in the use of virtual References:

  • Must be used with ReferenceQueue

  • The get method of phantom reference always returns null

  • When the garbage collector decides to recycle the phantom reference object, it inserts it into the ReferenceQueue.

The get() operation on the virtual reference always returns null because SF The get() method is implemented as follows:

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

    public T get() {
        return null;
    }

    public PhantomReference(T referent, ReferenceQueue<? super T> q) {
        super(referent, q);
    }

}

 

WeakHashMap class and its implementation

The WeakHashMap class is in Java In the util package, it implements the Map interface, which is an implementation of HashMap. It uses weak references as the storage scheme of internal data. WeakHashMap is a typical application of weak reference. It can be used as a simple cache table solution.

Use WeakHashMap to save a large amount of data:

public static void main(String[] args) {
    Map map = new WeakHashMap();

    for (int i = 0; i < 20000; i++) {
        map.put("key" + i, new byte[i]);
    }

    System.out.println(map.size());
}

// output: 24

Use - Xmx5M to limit the heap memory, and the normal operation of the code ends. If you replace WeakHashMap with HashMap, the code execution will throw an exception: Java lang.OutOfMemoryError: Java heap space

It can be seen that WeakHashMap will use weak references when the system memory is tight, and automatically release the memory data holding weak references.

However, if the key s of the WeakHashMap have strong references in the system, the WeakHashMap will degenerate into an ordinary HashMap because all table items cannot be cleaned up automatically.

Topics: Java