Let’s start with each of these references

Strong references: Objects that can be found through the GC ROOT object reference chain are not collected by the garbage collector, and can only be collected by the garbage collector if all GC roots do not reference the object by strong references.

SoftReference: if only the SoftReference references the object, the garbage collection is again initiated if the memory is insufficient after the garbage collection, and the SoftReference object is reclaimed. You can cooperate with the reference queue to release the SoftReference.

Weak references: When garbage collection occurs, only soft-referenced objects are collected by the garbage collector, regardless of whether memory is sufficient

Virtual Reference: must be used with the Reference queue, mainly used with ByteBuffer. When the referenced object is reclaimed, the virtual Reference will be put into the Reference queue, and the Reference Handler thread will call the virtual Reference method to release the direct memory.

Finalizer reference: In garbage collection, the Finalizer thread will find the referenced object through the Finalizer reference and call its Finalize method. Then, the referenced object can be collected in the second GC

The instance

Strong reference First we set the memory size to 20MB

    public class Demo2_3 {
        private static final int _4MB = 4 * 1024 * 1024;
        public static void main(String[] args) throws IOException {

            ArrayList<byte[]> list = new ArrayList<>();

            for (int i = 0; i < 5; i++) {
                list.add(new byte[_4MB]); } System.in.read(); }}Copy the code

Start main because strong references cannot be garbage collected and memory overflow occurs

Weak reference application scenario

public class Demo2_4 {

    private static final int _4MB = 4 * 1024 * 1024;

    // Soft reference. When the heap runs out of memory, it is reclaimed to free up memory
    public static void main(String[] args) throws IOException {
         //list --> SoftReference --> byte[] List references SoftReference --> Byte. [] List references SoftReference --> Byte
        List<SoftReference<byte[]>> list = new ArrayList<>();

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

        }
        System.out.println("End of loop:" + list.stream());
        for (SoftReference<byte[]> softReference : list) { System.out.println(softReference.get()); }}}Copy the code

Run:

Check the printed result. The program ran out of memory on the fourth loop and garbage collection was triggered. At this time, the previous soft reference object was reclaimed, so only the fifth object was not null in the printed result

We can also work with reference queues to free soft references themselves

public class Demo2_3 {

    private static final int _4MB = 4 * 1024 * 1024;

    public static void main(String[] args) throws IOException {
//list --> SoftReference --> byte[] List references SoftReference --> Byte. [] List references SoftReference --> Byte
        List<SoftReference<byte[]>> list = new ArrayList<>();
        // Reference queue
        ReferenceQueue<byte[]> queue = new ReferenceQueue<>();
        for (int i = 0; i < 5; i++) {
            // The reference object is associated with the reference queue. When the byte[] associated with the soft reference is reclaimed, the soft reference itself is added to the reference queue
            SoftReference<byte[]> ref = new SoftReference<>(new byte[_4MB],queue);
            System.out.println(ref.get());
            list.add(ref);
            System.out.println(list.size());

        }
        // The poll method removes the queue by getting the first element put into the queue
        // Retrieves unwanted soft reference objects from the queue and removes them
        Reference<? extends byte[]> poll = queue.poll();
        while(poll ! =null){
            list.remove(poll);
            poll = queue.poll();

        }
        System.out.println("End of loop:" + list.stream());
        for (SoftReference<byte[]> softReference : list) { System.out.println(softReference.get()); }}}Copy the code

Run the program:

The soft reference for the first four cycles has itself been released

Weak reference: example of application scenarios

public class Demo2_5 {

    private static final int _4MB = 4 * 1024 * 1024;

    public static void main(String[] args) {
        ArrayList<WeakReference<byte[]>> list = new ArrayList<>();
        for (int i = 0; i < 8; 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 loop:"+list.size()); }}Copy the code

Run the program: