reference type
Definition: the data type represented by the actual value reference of the type (similar to the pointer in C). If you assign a reference type to a variable, the variable references (or "points") the original value. Do not create any copies. Reference types include class, interface, delegate, and boxed value types.
About the parent class with the largest reference type (except Object)
public abstract class Reference extends Object
Classification of reference types
There are four reference types in java, strong, soft, weak and virtual
In versions prior to JDK 1.2, if an object was not referenced by any variables, the program could no longer use the object. That is, only when the object is reachable can the program use it.
Since JDK version 1.2, object references have been divided into four levels, so that programs can more flexibly control the life cycle of objects. The four levels from high to low are: strong reference, soft reference, weak reference and virtual reference.
Subclass of Reference ----- > >
Phantom reference,
Softreference,
WeakReference,
These are related to GC recycling, because the parent class Reference is related to GC;
Strong reference
public abstract class Reference extends Object
The abstract base class of the reference object. This class defines operations common to all reference objects. Because the reference object is implemented in close cooperation with the garbage collector, this class can not be subclassed directly.
Strong reference API
Strong references are the most commonly used references. If an object has a strong reference, the garbage collector will never recycle it
Code 3 ----- >
import java.io.IOException; class N{ @Override//This method is deprecated, but for demonstration, use it! protected void finalize(){ System.out.println("Recycled"); } } public class M { public static void main(String[] args) throws IOException { N n = new N(); n=null;//When n does not point to any object, it will be recycled by the garbage collector; It is uncertain when the jvm will recycle; System.gc();//Manually adjust the recycling; System.in.read(); } }
Since strong references are common, reference is an abstract class;
get() -- get reference
clear() method -- clear references
enqueue() - clear the reference. If there is a queue, it will be added to the queue. The return value is boolean
Isenqueueueued() -- check whether it has been cleared. If it is not registered in the queue before the reference is created -- that is, the enqueue method is not called (or the constructor parameter at the time of reference creation has no RQ), it will always return false;
Code 1 ----- >
ReferenceQueue RQ= new ReferenceQueue(); SoftReference<byte[]>softReference= new SoftReference<>(new byte[5*1024*1024],RQ); SoftReference<byte[]>softReference2= new SoftReference<>(new byte[5*1024*1024],RQ); SoftReference<byte[]>softReference3= new SoftReference<>(new byte[5*1024*1024],RQ); System.out.println(softReference.get());//Get the reference /* Thread.sleep(200);*/ // softReference.enqueue();// Clear the reference and put it in the queue softReference.clear();//Clear reference System.out.println(softReference.isEnqueued());//Check whether the enqueue() method gets true and clear () gets false System.out.println(softReference.get());
reachabilityFence(Object ref)
Ensure that the objects referenced by a given reference remain unchanged and strongly accessible, regardless of any objects that may become inaccessible before the program; Therefore, the referenced object is not a method that can be garbage collected at least after the call. Calling this method itself does not start garbage collection or complete.
Code 2 ----- >
public class SoftReferenceDemo { public static void main(String[] args) throws InterruptedException { //Set the heap memory size to 20M ReferenceQueue RQ= new ReferenceQueue(); SoftReference<byte[]> softReference= new SoftReference<>(new byte[10*1024*1024]); Reference.reachabilityFence(softReference); System.gc(); Thread.sleep(500); byte []bytes=new byte[15*1024*1024]; System.out.println(softReference.get()); } }
Virtual machine OOM error reported
If reference. Reachability fence (softreference) is commented out;
It will normally output -
Therefore, this method can keep the specified reference from being cleared by the virtual machine gc temporarily;
The public static void reachability fence (Object ref) method does not define any method body, but is completed through @ ForceInline annotation -- that is, forced inlining;
Simply put, most of the new objects are strong references;
Features of strong reference:
1. The most commonly used reference;
2. When the memory space is insufficient, the Java virtual machine would rather throw OutOfMemoryError to make the program terminate abnormally, rather than solve the problem of insufficient memory by arbitrarily recycling objects with strong references.
If the strong reference object is not used, it needs to be weakened to enable GC to recycle, as follows:
strongReference=null; The displayed setting is NULL
Or let it go beyond the life cycle of the object, the GC considers that there is no reference to the object, and then the object can be recycled. When to collect depends on the GC algorithm.
Feature 2 Demo:
Code 4 --- >
public class SoftReferenceDemo { public static void main(String[] args) { byte[]bytes= new byte[1024*1024*10]; System.out.println(bytes); byte[]byte2= new byte[1024*1024*15]; System.out.println(byte2); } }
I would rather throw errors than recycle strong references pointed by references;
(if your JVM does not throw an error, it indicates that the allocated space of your JVM is large enough;)
How to set the maximum and minimum heap space - (temporary, not global)
Set - Xms20M -Xmx20M in VM optionss
Reference count: in the Java heap, each object will have a reference count attribute to record the number of references. For each reference, the count will increase by 1, and for each release, the count will decrease by 1.
There is a strong reference inside a method, that is, the local variable is a strong reference type, the reference (address) is saved in the Java stack, and the real reference content (Object) is saved in the Java heap.
When the method runs, the strong reference will exit the method stack and the reference count will return to 0. When the reference count returns to 0, the object will be recycled by the garbage collector.
However, if the strong reference is a global variable, it needs to be assigned null when the object is not used, because the strong reference will not be recycled by the garbage collector, see code 3
Soft reference ----- > > >
When the heap memory space is enough, even if you actively call GC, it will not be recycled immediately. Instead, you will notify the garbage collector that it will be recycled in the future. When will it be recycled ------ > > > the object will be recycled when the heap memory space is insufficient; Therefore, soft references are often used for caching;
Code 5 --- >
import java.lang.ref.SoftReference; import java.util.concurrent.TimeUnit; public class SoftReferenceDemo { public static void main(String[] args) throws InterruptedException { //A 10M byte array is referenced SoftReference<byte[]>softReference= new SoftReference<>(new byte[1024*1024*10]); //Print this reference before recycling System.out.println(softReference.get()); //recovery System.gc(); //Thread.sleep(100); TimeUnit.SECONDS.sleep(1); //Print the reference after recycling System.out.println(softReference.get()); //Then came a reference with a size of 15M SoftReference<byte[]>softReference1= new SoftReference<>(new byte[1024*1024*15]); //Strong reference is also OK, as long as the heap space is not enough; //byte b[]=new byte[1024*1024*15]; //Print it again System.out.println(softReference.get());//null } }
Soft referenced API ------ > > >
Inheritance implementation relationship of class
public class SoftReference extends Reference
Class description:
The soft reference object is cleared by the garbage collector itself in response to memory requirements. Soft reference is the most commonly used implementation of memory sensitive caching.
Suppose the garbage collector determines that the object is soft reachable at some point in time. At this point, it can choose to atomically clear all soft references to the object and any other soft accessible objects that can access the object through a strong reference chain. At the same time or later, it will put those newly cleared soft references registered in the reference queue into the queue.
All soft references to soft reachable objects are guaranteed to be cleared before the virtual machine throws OutOfMemoryError.
Otherwise, there is no limit on the time when soft references are cleared or the order in which a set of such references to different objects are cleared. However, virtual machine implementations are encouraged to prefer to clear recently created or recently used soft references.
The simple understanding is that soft references must be cleaned up before the virtual machine throws OOM; If the virtual machine memory domain value is not reached, no operation will be done to clear the domain soft reference;
Construction method - >
The difference between the two construction methods is that one is registered in the queue and the other is not registered in the queue;
Code 6 ------ > > >
String str="HelloWorld"; ReferenceQueue rq= new ReferenceQueue(); SoftReference<String>reference=new SoftReference<>(str,rq); String s = reference.get();//Get this string System.out.println(s); str=null; System.gc();//Notify recycling to see if it can be recycled System.out.println(reference.get()); System.out.println("------------------Fenberg County---------------"); SoftReference<String>reference2=new SoftReference<>(str); String str1 = reference.get();//Get this string System.out.println(str1); str=null; System.gc();//Notify recycling to see if it can be recycled System.out.println(reference.get());
You can see that when the JVM has enough memory, it will not be actively cleared
Source code of get method - > > >
Recycling of soft references when JVM memory is not enough ----- > > >
Code 7 --- >
public class SoftReferenceDemo { public static void main(String[] args) throws InterruptedException { ReferenceQueue RQ= new ReferenceQueue(); SoftReference<byte[]>softReference= new SoftReference<>(new byte[8*1024*1024]); System.out.println(softReference.get()); SoftReference<byte[]>softReference2= new SoftReference<>(new byte[8*1024*1024]); System.out.println(softReference2.get()); System.gc(); Thread.sleep(10000); byte []bytes2= new byte[5*1024*1024]; System.out.println(softReference.get()); System.out.println(softReference2.get()); } }
Operation results ----- >
Sometimes this is the result,
Sometimes it's another result
Although the virtual machine encourages recycling implementation, and prefers to clear the recently created or recently used soft references - I tried this sentence to mean that the latest one is relative to the newly created soft reference, it does not guarantee that other soft references will not be recycled------- It can be understood that – keep the latest one;
When the number of soft references is increased to three
It can be found that all will still be removed, indicating that even if it is encouraged, it may not be recycled;
Let's look at the reference queue ------ > > >
Code 8 ------ > > > > >
public class SoftReferenceDemo { public static void main(String[] args) throws InterruptedException { ReferenceQueue RQ= new ReferenceQueue(); SoftReference<byte[]>softReference= new SoftReference<>(new byte[5*1024*1024],RQ); SoftReference<byte[]>softReference2= new SoftReference<>(new byte[5*1024*1024],RQ); SoftReference<byte[]>softReference3= new SoftReference<>(new byte[5*1024*1024],RQ); System.out.println(softReference.get()); System.out.println(softReference2.get()); System.out.println(softReference3.get()); /*null because there is no gc() at this time*/ Reference poll1 = RQ.poll(); System.out.println(poll1);//null System.gc(); Thread.sleep(5000); byte []bytes2= new byte[8*1024*1024]; System.out.println(softReference.get()); System.out.println(softReference2.get()); System.out.println(softReference3.get()); Reference poll = RQ.poll();//After gc, the soft reference is added to the queue. If there is an available soft reference in the queue, the reference is returned immediately and deleted from the queue System.out.println(poll); } }
Three methods in ReferenceQueue ----- > > >
public Reference<? extends T> poll()
Polls this queue to see if a reference object is available. If one is available without further delay then it is removed from the queue and returned. Otherwise this method immediately returns .null
When a SoftReference (t referent, ReferenceQueue <? Super T > q) is constructed, a soft referenced object will be added to the queue Q after gc;
If the poll must return null before the gc() call;
Code 9 ------ >
public class SoftReferenceDemo { public static void main(String[] args) throws InterruptedException { ReferenceQueue RQ= new ReferenceQueue(); SoftReference<byte[]>softReference= new SoftReference<>(new byte[5*1024*1024],RQ); SoftReference<byte[]>softReference2= new SoftReference<>(new byte[5*1024*1024],RQ); SoftReference<byte[]>softReference3= new SoftReference<>(new byte[5*1024*1024],RQ); System.out.println(softReference.get()); System.out.println(softReference2.get()); System.out.println(softReference3.get()); /* *//*null because there is no gc() at this time*//* Reference poll1 = RQ.poll(); System.out.println(poll1);//null*/ /* Reference remove = RQ.remove();//Block method until timeout System.out.println(remove);*/ System.gc(); Thread.sleep(5000); byte []bytes2= new byte[8*1024*1024]; System.out.println("--------------"); System.out.println(softReference.get()); System.out.println(softReference2.get()); System.out.println(softReference3.get()); /* Reference poll = RQ.poll();//gc The soft reference is then added to the queue. If there is an available soft reference in the queue, the reference is immediately returned and deleted from the queue System.out.println(poll);*/ Reference remove1 = RQ.remove(); System.out.println(remove1); } }
remove method source code ---- > >
Weak reference ----- > > >
Code 10 --- >
import java.lang.ref.WeakReference; class A { @Override protected void finalize() { System.out.println("finalize--invoke"); } } public class WeakReferenceDemo { public static void main(String[] args) throws InterruptedException { WeakReference<A> weak = new WeakReference<>(new A()); System.out.println(weak.get()); Thread.sleep(200); System.gc(); System.out.println(weak.get()); } }
Results --------- >
Whenever gc sees a weak reference, it will directly recycle the weak reference;
Inheritance implementation relationship----
public class WeakReference extends Reference
The construction method is similar to soft reference;
According to the characteristics of weak references - as long as gc sees weak references, it will directly recycle weak references;
Weakly referenced API
WeakReference(T referent)
Creates a new weak reference that references the given object.
WeakReference(T referent, ReferenceQueue<? super T> q)
Creates a new weak reference that references the given object and is registered in the given queue.
Application of weak reference in ThreadLocal class
public class WeakReferenceDemo { public static void main(String[] args) throws InterruptedException, IOException { ThreadLocal<A>tl= new ThreadLocal<>(); tl.set(new A()); tl.remove(); } }
Break point of set method ----- > >
Memory leak means that there is an object in memory that will never be recycled, but this object is not used elsewhere. The garbage collector can see that it is a strong reference type
It will not take the initiative to recycle it, so memory leakage will occur;
Let's analyze the possibility of memory leakage through set() in ThreadLocal class!!
1. If the static internal class entry in ThreadLocal is not a weak reference, but a strong reference type;
When the ThreadLocal object points to null, the whole tl object should be recycled by GC. However, since the Entry [] in ThreadLocal points to a strong reference object, the ThreadLocal will never be recycled. Although it is not needed, it cannot be recycled, so memory leakage will occur;
2. Similarly, if it is a soft reference type, memory leakage may occur (when there is enough memory)
3. Only weak references are appropriate;
Memory overflow - refers to memory overflow caused by insufficient memory, that is, OOM
Note: if an object is used occasionally (rarely), and you want to get it at any time when you use it, but you don't want to affect the garbage collection of this object, you should use Weak Reference to remember this object.
Life cycle of weak references ----- > >
The life cycle of the WeakReference object is basically determined by the garbage collector. Once the garbage collection thread finds a weak reference object, it will be recycled in the next GC process.
Virtual reference
public class PhrReferenceDemo { public static void main(String[] args) { ReferenceQueue rq = new ReferenceQueue(); PhantomReference<byte[]> phantomReference = new PhantomReference<>(new byte[10 * 1024 * 1024], rq); System.out.println(phantomReference.get());//The obtained value is null -- the virtual reference cannot be obtained directly //Reference.reachabilityFence(rq); phantomReference.enqueue();//Remove the reference and add it to the queue if (rq.poll() != null) { //Indicates that a virtual reference has entered the queue, System.out.println("Can be recycled"); System.gc(); } byte[] bytes = new byte[8 * 1024 * 1024]; // phantomReference.enqueue();// Remove and join the queue, and return the removed object immediately // System.out.println(phantomReference.isEnqueued()); System.out.println(phantomReference.get());//The obtained value is null -- the virtual reference cannot be obtained directly } }
Virtual reference API
Inheritance implementation relationship ---- >
public class PhantomReference extends Reference
Phantom references objects and queues after the collector to determine that their references may be recycled. Phantom references are most commonly used to schedule post cleanup operations.
Construction method ----- > > it can be seen that there is only one construction, and a reference queue must be added
Virtual reference ---- when you can't get it when it's worth getting, is it still necessary to have a virtual reference?
Virtual references are mainly used to track the activities of objects collected by the garbage collector. They are generally used when writing a JVM virtual machine. Virtual references can point to any object,
It may be used when cleaning up the out of heap memory. How to clean up the out of heap memory?
Some methods can be used to make virtual references enter the queue, and then judge whether there are virtual references in the queue to deal with some situations;
Summary ------ > > >