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 type | Garbage collection time | purpose | survival time |
---|---|---|---|
Strong reference | Never | General state of the object | Terminate when JVM stops running |
Soft reference | When memory is low | Object cache | Terminate when memory is low |
Weak reference | During garbage collection | Object cache | Termination after gc run |
Virtual reference | Unknown | Unknown | Unknown |
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()); } }