https://blog.csdn.net/qq_39192827/article/details/85611873
We want some objects to remain in memory when there is enough memory; If there is not enough memory, these objects can be discarded, and four reference types are proposed.
There are two main purposes of providing these four reference types in Java: first, it allows programmers to determine the life cycle of some objects through code; The second is to facilitate JVM garbage collection.
Strong reference: if an object has a strong reference, it will not be collected by the garbage collector. When memory space is insufficient, Java Virtual machine would rather throw OutOfMemoryError Error, causing the program to terminate abnormally, and this object is not recycled. Soft reference: it is used to describe some useful but not necessary objects, only when there is insufficient memory JVM To recycle the object Weak reference: used to describe non essential objects when JVM During garbage collection, objects associated with weak references will be recycled regardless of whether there is enough memory Virtual reference: if an object is associated with a virtual reference, it may be recycled by the garbage collector at any time. Virtual references are mainly used to track the activity of objects being garbage collected.
1, Strong reference
Strong references are commonly used in practice.
Object object = new Object(); String str = "StrongReference";
If an object has a strong reference, it will not be collected by the garbage collector. When the memory space is insufficient, the Java virtual machine would rather throw OutOfMemoryError to make the program terminate abnormally than recycle this object.
If you want to break the association between a strong reference and an object, you can explicitly assign the reference to null, so that the JVM will recycle the object at the right time.
For example, in the clear method of the ArrayList class, the cleanup is implemented by assigning a reference to null
public void clear() { modCount++; // Let gc do its work for (int i = 0; i < size; i++) elementData[i] = null; size = 0; }
A private variable elementData array is defined in the ArrayList class. When calling the method to empty the array, you can see that each array content is assigned null. Unlike elementData=null, strong references still exist, avoiding reallocation of memory when adding elements in subsequent calls to add() and other methods. The method of releasing memory in the clear() method is especially suitable for the reference types stored in the array, so that memory can be released in time.
2, Soft reference
Soft reference is used to describe some useful but not necessary objects. In Java, Java Lang.ref.softreference class. For objects associated with soft references, the JVM will recycle the object only when there is insufficient memory. Therefore, this can be well used to solve the problem of OOM, and this feature is very suitable for caching: such as web page caching, image caching, etc.
A soft reference can be used in conjunction with a reference queue. If the object referenced by the soft reference is recycled by the JVM, the soft reference will be added to the reference queue associated with it.
import java.lang.ref.SoftReference; public class SoftRef { public static void main(String[] args){ System.out.println("start"); Obj obj = new Obj(); SoftReference<Obj> sr = new SoftReference<Obj>(obj); obj = null; System.out.println(sr.get()); System.out.println("end"); } } class Obj{ int[] obj ; public Obj(){ obj = new int[1000]; } }
When the memory is large enough, the array can be stored in the soft reference, and the data can be fetched from the memory when fetching data, so as to improve the operation efficiency
Soft reference has important applications in practice:
-
The back button of the browser. The web page content displayed during the back can be requested again or removed from the cache:
(1) If a web page is recycled at the end of browsing, you need to rebuild it when you press back to view the previously viewed page
(2) If the browsed web page is stored in memory, it will cause a lot of memory waste and even memory overflow. At this time, soft reference can be used
-
Soft references are used in the cache. If there is free memory, the cache can be reserved temporarily and cleaned up when the memory is insufficient. This ensures that the cache will not run out of memory at the same time
3, Weak reference
Weak references are also used to describe non essential objects. When the JVM garbage collects, the objects associated with weak references will be recycled regardless of whether the memory is sufficient or not. In java, use java Lang.ref.weakreference class.
The difference between weak references and soft references is that objects with only weak references have a shorter life cycle. When the garbage collector thread scans the memory area under its jurisdiction, once it finds an object with only weak references, it will reclaim its memory regardless of whether the current memory space is sufficient or not. However, since the garbage collector is a low priority thread, it is not necessary to quickly find objects with only weak references. Therefore, objects associated with soft references will only be recycled when there is insufficient memory, while objects associated with weak references will always be recycled when the JVM garbage collects.
import java.lang.ref.WeakReference; public class WeakRef { public static void main(String[] args) { //When you want to obtain the object referenced by the weak reference, you first need to judge whether it has been recycled. If WR If the get () method is empty, the object pointed to by weakCar has been recycled. WeakReference<String> sr = new WeakReference<String>(new String("hello")); System.out.println(sr.get()); System.gc(); //Notify the gc of the JVM to garbage collect System.out.println(sr.get()); } }
Operation results:
hello null
When using soft references and weak references, we can use system GC () to notify the JVM of garbage collection. However, it should be noted that although the notification is sent, the JVM does not necessarily execute it immediately, that is, this sentence cannot ensure that the JVM will garbage collection at this time.
The weak reference can also be used in conjunction with a reference queue. If the object referenced by the weak reference is garbage collected, the Java virtual machine will add the weak reference to the associated reference queue.
Application scenario: if an object is used occasionally, and you want to get it at any time, but you don't want to affect the garbage collection of this object, you should use the Weak Reference to remember this object. Or you want to reference an object, but the object has its own life cycle. You don't want to intervene in the life cycle of the object. At this time, you should use a Weak Reference. This reference will not have any additional impact on the garbage collection judgment of the object.
Do L2 cache, etc.
4, Virtual reference
Unlike previous soft and weak references, virtual references do not affect the life cycle of objects. In java, use java The lang.ref.phantomreference class represents. 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 mainly used to track the activity of objects being garbage collected.
The virtual reference must be associated with the reference queue. When the garbage collector prepares to recycle an object, if it finds that it still has a virtual reference, it will add the virtual reference to the associated reference queue. The program can know whether the referenced object will be garbage collected by judging whether a 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.
import java.lang.ref.PhantomReference; import java.lang.ref.ReferenceQueue; public class PhantomRef { public static void main(String[] args) { ReferenceQueue<String> queue = new ReferenceQueue<String>(); PhantomReference<String> pr = new PhantomReference<String>(new String("hello"), queue); System.out.println(pr.get()); } }