Strong reference, soft reference, weak reference, false reference (strong weak weak)

Posted by gazfocus on Sun, 09 Jan 2022 18:28:55 +0100

Java has introduced four references since version 1.2, and the four references range from high to low:

Strong Reference>Soft Reference>Weak Reference>Virtual Reference

1. Strong References (Never Recycle)

If an object has a strong reference, the garbage collector will never recycle it. When there is insufficient memory space, the Java virtual machine would rather throw an OutOfMemoryError error, causing the program to terminate abnormally, or reclaim objects with strong references at will to solve the problem of insufficient memory.

public class StrongReferenceDemo {

    public static void main(String[] args) {
        Object o1 = new Object();
        Object o2 = o1;
        o1 = null;
        System.gc();
        System.out.println(o2); //java.lang.Object@14ae5a5
    }
}

2. Soft References (Out of Memory Recycling)

Soft references are used to describe something useful but not necessary, using Java in Java. The lang.ref.SoftReference class represents the.

If an object has only soft references, there is enough memory space for the garbage collector to not recycle it; If there is not enough memory space, the memory of these objects will be reclaimed. This object can be used by programs as long as the garbage collector does not recycle it. Soft references can be used to implement memory-sensitive caching.

package cn.linwillen.base.ref;

import java.lang.ref.SoftReference;

/**
 * @author linwillen
 * @create 2022-01-10 0:19
 */
public class SoftReferenceDemo {

    /**
     * When there is enough memory
     */
    public static void softRefMemoryEnough(){
        Object o = new Object();
        SoftReference<Object> softReference = new SoftReference<>(o);
        System.out.println(o); //java.lang.Object@14ae5a5
        System.out.println(softReference.get()); //java.lang.Object@14ae5a5

        o = null;
        System.gc();
        System.out.println(o); //null
        System.out.println(softReference.get()); //java.lang.Object@14ae5a5
    }

    public static void softRefMemoryNotEnough(){
        Object o = new Object();
        SoftReference<Object> softReference = new SoftReference<>(o);
        System.out.println(o);
        System.out.println(softReference.get());

        o = null;
        try {
            byte[] bytes = new byte[30 * 1024 * 1024];
        }catch (Throwable e){
            e.printStackTrace();
        }finally {
            System.out.println(o);
            System.out.println(softReference.get());
        }

    }

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

Configure jvm memory size to 5m and print gc information

 

Run result:

[GC (Allocation Failure) [PSYoungGen: 1024K->488K(1536K)] 1024K->568K(5632K), 0.0015137 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
java.lang.Object@14ae5a5
java.lang.Object@14ae5a5
[GC (Allocation Failure) [PSYoungGen: 1248K->488K(1536K)] 1328K->688K(5632K), 0.0011138 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 488K->488K(1536K)] 688K->704K(5632K), 0.0006997 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (Allocation Failure) [PSYoungGen: 488K->0K(1536K)] [ParOldGen: 216K->643K(4096K)] 704K->643K(5632K), [Metaspace: 3277K->3277K(1056768K)], 0.0066857 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
[GC (Allocation Failure) [PSYoungGen: 0K->0K(1536K)] 643K->643K(5632K), 0.0002589 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (Allocation Failure) [PSYoungGen: 0K->0K(1536K)] [ParOldGen: 643K->625K(4096K)] 643K->625K(5632K), [Metaspace: 3277K->3277K(1056768K)], 0.0072145 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] 
null
null
Heap
 PSYoungGen      total 1536K, used 65K [0x00000000ffe00000, 0x0000000100000000, 0x0000000100000000)
  eden space 1024K, 6% used [0x00000000ffe00000,0x00000000ffe106c0,0x00000000fff00000)
  from space 512K, 0% used [0x00000000fff80000,0x00000000fff80000,0x0000000100000000)
  to   space 512K, 0% used [0x00000000fff00000,0x00000000fff00000,0x00000000fff80000)
 ParOldGen       total 4096K, used 625K [0x00000000ffa00000, 0x00000000ffe00000, 0x00000000ffe00000)
  object space 4096K, 15% used [0x00000000ffa00000,0x00000000ffa9c500,0x00000000ffe00000)
 Metaspace       used 3308K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 362K, capacity 388K, committed 512K, reserved 1048576K
java.lang.OutOfMemoryError: Java heap space
	at cn.linwillen.base.ref.SoftReferenceDemo.softRefMemoryNotEnough(SoftReferenceDemo.java:34)
	at cn.linwillen.base.ref.SoftReferenceDemo.main(SoftReferenceDemo.java:46)


Soft references can be used in conjunction with a reference queue, which is added to the reference queue associated with the Java virtual machine if the object referenced by the soft reference is recycled by the garbage collector.

When memory is large enough, the array can be stored in a soft reference, and when data is fetched, the data can be fetched from memory to improve efficiency.

Soft references are important applications in practice, such as the browser's back button, where the content of the page displayed can be re-requested or retrieved from the cache:

  1. If a page recycles its content at the end of a browse, it needs to be rebuilt when you press Back to view the previously browsed page
  2. Soft references can be used when storing pages you've visited in memory can cause a lot of memory waste and even memory overflow

3. Weak references (gc is recycled)

Weak references are also used to describe objects that are not required, and when the JVM garbage collects, objects associated with weak references are recycled regardless of sufficient memory. In java, use java. The lang.ref.WeakReference class represents the.

The difference between a weak reference and a soft reference is that an object with only a weak reference has a shorter life cycle. When a garbage collector thread scans the memory area under its jurisdiction, it reclaims the memory of an object with only weak references, regardless of whether the current memory space is sufficient or not. However, since the garbage collector is a low priority thread, it is not always possible to quickly discover objects with only weak references.

A weak reference can be used in conjunction with a reference queue, and if the object referenced by the weak reference is garbage collected, the Java virtual machine will add the weak reference to the reference queue associated with it.

package cn.linwillen.base.ref;

import java.lang.ref.WeakReference;

/**
 * @author linwillen
 * @create 2022-01-10 0:46
 */
public class WeakReferenceDemo {

    public static void main(String[] args) {
        Object o = new Object();
        WeakReference<Object> softReference = new WeakReference<>(o);
        System.out.println(o);
        System.out.println(softReference.get());
        System.out.println("=================");
        o = null;
        System.gc();
        System.out.println(o);
        System.out.println(softReference.get());
    }
}

Run Results

java.lang.Object@14ae5a5
java.lang.Object@14ae5a5
=================
null
null

Know WeakHashMap?

package cn.linwillen.base.ref;

import java.util.WeakHashMap;

/**
 * @author linwillen
 * @create 2022-01-10 0:55
 */
public class WeakHashMapDemo {

    public static void myWeakHashMap() {
        WeakHashMap<Integer, String> weakHashMap = new WeakHashMap<>();
        Integer key = new Integer(1);
        weakHashMap.put(key,"WeakHashMap");
        System.out.println(weakHashMap);
        key = null;
        System.out.println(weakHashMap);
        System.gc();
        System.out.println(weakHashMap+"\t"+weakHashMap.size());

    }

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

Run Results

{1=WeakHashMap}
{1=WeakHashMap}
{}	0

4. Virtual references (null as never)

As the name implies, virtual references refer to the same form as fictitious, and differ from several other references. Virtual references do not determine the life cycle of an object. Use Java in java. The lang.ref.PhantomReference class representation. If an object is associated with a virtual reference, it may be recycled by the garbage collector at any time, just as no reference is associated with it. Virtual references are primarily used to track object garbage collection activities.

Reference queue: When an object is garbage collected, a reference to that object is put in the queue

package cn.linwillen.base.ref;

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

/**
 * @author linwillen
 * @create 2022-01-10 1:05
 */
public class ReferenceQueueDemo {

    public static void main(String[] args) {
        Object o = new Object();
        ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
        WeakReference<Object> weakReference = new WeakReference<Object>(o,referenceQueue);

        System.out.println(o);
        System.out.println(weakReference.get());
        System.out.println(referenceQueue.poll());

        System.out.println("=====================");
        o = null;// This step is required to set the null object to be recycled
        System.gc();
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(o);
        System.out.println(weakReference.get());
        System.out.println(referenceQueue.poll());


    }
}

Run results

java.lang.Object@14ae5a5
java.lang.Object@14ae5a5
null
=====================
null
null
java.lang.ref.WeakReference@7f31245a

Virtual references are primarily used to track the activity of objects being recycled by the garbage collector. One difference between a virtual reference and a soft reference and a weak reference is that a virtual reference must be used in conjunction with a reference queue. When the garbage collector is ready to recycle an object, if it finds a dummy reference, it adds the dummy reference to the reference queue associated with it before recycling the object's memory.

package cn.linwillen.base.ref;

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;

/**
 * @author linwillen
 * @create 2022-01-10 1:15
 */
public class PhantomReferenceDemo {

    public static void main(String[] args) {
        Object o = new Object();
        ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
        PhantomReference<Object> phantomReference = new PhantomReference<Object>(o,referenceQueue);

        System.out.println(o);
        System.out.println(phantomReference.get());
        System.out.println(referenceQueue.poll());


        o = null;
        System.out.println("===================");
        System.gc();

        System.out.println(o);
        System.out.println(phantomReference.get());
        System.out.println(referenceQueue.poll());

    }
}

Run Results

java.lang.Object@14ae5a5
null
null
===================
null
null
java.lang.ref.PhantomReference@7f31245a

Topics: Java jvm Back-end