There are four kinds of references in Java - strong reference, soft reference, weak reference and virtual reference

1. Strong reference

Strong references are the most common kind of references. 99.9999% of the codes we write are strong references:

2. Soft reference

Soft reference is to wrap the object with SoftReference. When we need to get the wrapped object from the soft reference object, we just need to get it
characteristic:
When the memory is insufficient, the JVM GC will be triggered. If the memory is still insufficient after GC, the wrapped objects of soft reference will be killed
That is, the JVM will recycle the object only when there is insufficient memory.

SoftReference<Student> studentSoftReference=new SoftReference<Student>(new Student());
Student student = studentSoftReference.get();
System.out.println(student);
  • Simulate recycling soft references
    • Set the maximum heap memory to 20M -Xmx20M
public static void main(String[] args) {
    SoftReference softReference=new SoftReference(new byte[1024 * 1024 * 10]);
    System.out.println(softReference.get());
    System.gc();
    //After manual garbage collection, it is found that there is not enough memory. So soft references are not recycled
    System.out.println(softReference.get());
      //Cause insufficient memory and conduct a garbage collection. Memory is still low after garbage collection. The soft reference is recycled
    byte[] bytes = new byte[1024 * 1024 * 10];
    System.out.println(softReference.get());
}
  • Output results

3. Weak reference

The use of weak references is similar to that of soft references, except that the keyword becomes WeakReference
characteristic:
The feature of weak reference is that no matter whether the memory is enough or not, as long as GC occurs, it will be recycled:

WeakReference<byte[]> weakReference = new WeakReference<byte[]>(new byte[1]);
System.out.println(weakReference.get());
System.gc();
System.out.println(weakReference.get());
  • Output results

4. Virtual reference

Virtual references need to be used together with ReferenceQueue (put objects and queues into virtual references)
When GC occurs, the object pointed to by the virtual reference will be recycled, and the virtual reference associated with the object (that is, the reference) will be placed in the ReferenceQueue

effect:
This is what we rely on when reclaiming direct memory

  • Simulate the process of reclaiming direct memory
    • Create a low-level thread to listen to the queue associated with the virtual reference all the time
    • Once the queue has content, it will be stored according to the entry address of the queue. To execute related methods (free direct memory)
ReferenceQueue queue = new ReferenceQueue();
PhantomReference<byte[]> reference = new PhantomReference<byte[]>(new byte[1], queue);
System.out.println(reference.get());
public static void main(String[] args) {

    ReferenceQueue queue = new ReferenceQueue();
    List<byte[]> bytes = new ArrayList<>();
    PhantomReference<Test2> reference = new PhantomReference<Test2>(new Test2(),queue);
    //This thread is mainly used to cause heap overflow and then garbage collection
    new Thread(() -> {
        for (int i = 0; i < 100;i++ ) {
            bytes.add(new byte[1024 * 1024]);
        }
    }).start();

   //This thread keeps listening to the queue associated with the virtual reference. When there is something in the queue, it indicates that the object of the virtual reference has been recycled
    new Thread(() -> {
        while (true) {
            //Get the contents in the queue
            Reference poll = queue.poll();
            if (poll != null) {
                System.out.println("Virtual references were recycled:" + poll);
            }
        }
    }).start();
    
   Scanner scanner = new Scanner(System.in);
    scanner.hasNext();
}
  • Output results

5. Summary

reference typeGarbage collection timepurposesurvival time
Strong referenceNeverGeneral state of the objectTerminate when JVM stops running
Soft referenceWhen memory is lowObject cacheTerminate when memory is low
Weak referenceDuring garbage collectionObject cacheTermination after gc run
Virtual referenceUnknownUnknownUnknown

6. Soft reference examples

1. Simply put

Both soft and weak references can be associated with a queue, but it is not necessary
When referenced objects are recycled, they themselves are put in the queue

2. Examples

Function:
Set heap memory size 20M
Add 5 bytes of 4M size to the list circularly (the bytes are wrapped with SoftReference)
In this way, when the memory is insufficient, the memory will be recycled (and the SoftReference in the list will be removed), rather than throwing an exception

package cn.itcast.jvm.t2;

import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.List;

/**
 * Demonstrate soft reference, cooperate with reference queue
 */
public class Demo2_4 {
    private static final int _4MB = 4 * 1024 * 1024;

    public static void main(String[] args) {
        List<SoftReference<byte[]>> list = new ArrayList<>();

        // Reference queue
        ReferenceQueue<byte[]> queue = new ReferenceQueue<>();

        for (int i = 0; i < 5; i++) {
            // The reference queue is associated. When the byte [] associated with the soft reference is recycled, the soft reference will be added to the queue itself
            SoftReference<byte[]> ref = new SoftReference<>(new byte[_4MB], queue);
            System.out.println(ref.get());
            list.add(ref);
            System.out.println(list.size());
        }

        // Get the useless soft reference object from the queue and remove it
        //poll() returns the SoftReference
        Reference<? extends byte[]> poll = queue.poll();
        while( poll != null) {
            list.remove(poll);
            poll = queue.poll();
        }

        System.out.println("===========================");
        for (SoftReference<byte[]> reference : list) {
            System.out.println(reference.get());
        }

    }
}

7. Weak reference instance

1. Usage

The usage is the same as that of soft reference
There is only a difference between weak references and soft references

2. Examples

When there is not enough memory, execute GC, and then the weak reference will be recycled once

package cn.itcast.jvm.t2;

import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

/**
 * Show me weak references
 * -Xmx20m -XX:+PrintGCDetails -verbose:gc
 */
public class Demo2_5 {
    private static final int _4MB = 4 * 1024 * 1024;

    public static void main(String[] args) {
        //  list --> WeakReference --> byte[]
        List<WeakReference<byte[]>> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            WeakReference<byte[]> ref = new WeakReference<>(new byte[_4MB]);
            list.add(ref);
            for (WeakReference<byte[]> w : list) {
                System.out.print(w.get()+" ");
            }
            System.out.println();

        }
        System.out.println("End of cycle:" + list.size());
    }
}

Keywords: Java jvm

Added by chord on Wed, 09 Feb 2022 04:15:23 +0200