In Java, three reference classes are defined in the Java.lang.ref package, namely soft, weak, and virtual references. These 3 classes provide a convenient mechanism for interacting with garbage collection mechanisms and providing a mechanism for caching, so what does this three class cause?
SoftReference:
If an object has only soft references, enough memory space is available, the garbage collector does not recycle it, and if the memory space is insufficient, the memory of those objects is reclaimed. The object can be used by the program as long as it is not reclaimed by the garbage collector. Soft references can be used to implement memory-sensitive caches (see below for an example).
A soft reference can be used in conjunction with a reference queue (Referencequeue), and if the object referenced by the soft reference is reclaimed by the garbage collector, the Java Virtual machine will add the soft reference to the reference queue associated with it.
WeakReference:
The difference between a weak reference and a soft reference is that the weakly referenced object has a more ephemeral life cycle. As the garbage collector thread scans the area of memory it governs, once an object with only a weak reference is found, its memory is reclaimed, regardless of whether the current memory space is sufficient or not. However, because the garbage collector is a low-priority thread, it is not necessarily quick to discover objects that have only weak references.
A weak reference can be used in conjunction with a reference queue (Referencequeue), and if the object referenced by the weak reference is garbage collected, the Java virtual machine adds the weak reference to the reference queue associated with it.
Phatomreference:
Virtual Reference "as the name implies, is the form of a dummy, and several other references are different, virtual reference does not determine the life cycle of the object." If an object holds only virtual references, it can be reclaimed by the garbage collector at any time, just as there are no references.
Virtual references are primarily used to track activities that objects are reclaimed by the garbage collector. One difference between a virtual reference and a soft reference and a weak reference is that the virtual reference must be used in conjunction with the reference queue (Referencequeue). When the garbage collector prepares to reclaim an object, if it finds that it has a virtual reference, it will add the virtual reference to the reference queue associated with it before reclaiming the object's memory.
So, as you can see from these definitions, reference provides a mechanism for whether weak references can be taken to objects that are saved to the head after a strong reference disappears, and the system GC mechanism is a factor to consider.
Here are a few examples of how these reference are used.
1. Strong references exist
ReferenceQueue<Person> queue = new ReferenceQueue<Person> (); person softperson = new person (); softperson.setid (1); softperson.setage ( softperson.setname) ("Zhangsan"); person weakperson = new person (); Weakperson.setid (2); weakperson.setage (+); weakperson.setname (" Lisi "); person phantomperson = new person (); phantomperson.setid (3); phantomperson.setage (; ) Phantomperson.setname ("Wangwu"); softreference<person> softref = New softreference<person> (Softperson); weakreference<person> Weakref = new weakreference<pErson> (Weakperson); phantomreference<person> phantomref = new PhantomReference<Person> (phantomperson, queue); ////////// softrefernece//////////////////////////////////// try { system.out.println (Softref.get (). GetName ()); } catch (exception e) { e.printstacktrace (); } ////////////////////weakreference////////////////////////////////// / try { system.out.println ( Weakref.get (). GetName ()); } catch (exception e) { e.printstacktrace (); } /////////// phatomreference////// try { System.out.println (Phantomref.get (). GetName ()); } catch (exception e) { e.printstacktrace (); }}
Zhangsanjava.lang.NullPointerExceptionlisiat Com.app.client.RefClient.main (refclient.java:53) at SUN.REFLECT.NATIVEMETHODACCESSORIMPL.INVOKE0 (Native Method) at Sun.reflect.NativeMethodAccessorImpl.invoke ( nativemethodaccessorimpl.java:57) at Sun.reflect.DelegatingMethodAccessorImpl.invoke ( delegatingmethodaccessorimpl.java:43) at Java.lang.reflect.Method.invoke (method.java:606) at Com.intellij.rt.execution.application.AppMain.main (appmain.java:140)
In the case where a strong reference is still present, the Get () method of the virtual reference (phatomreference) returns a null, why?
public class phantomreference<t> extends reference<t> { /** * constructs a new phantom reference and registers it with the given * reference queue . the reference queue may be {@code null}, but this case * does not make any sense, since the reference will never be enqueued, and * the {@ link #get ()} method always returns {@code null}. * * @param r the referent to track * @param q the queue to register the phantom reference object With */ public phantomreference (T r, REFERENCEQUEUE<?&NBSP;SUPER&NBSP;T>&NBSP;Q) { super ( R,&NBSP;Q); } /** * returns {@code null}. The referent of a phantom reference is not * accessible. * * @return {@code null} (always) */ @Override public t get () { return null; }}
You can see from the source that the get () method always returns NULL, so what is the use of this phatomreference class, which we put in the final explanation. Now consider only the SoftReference and WeakReference two references.
2. Breaking Strong references
Softperson = Null;weakperson = null;////////////////////softrefernece////////////////////////////////////try { System.out.println (Softref.get (). GetName ());} catch (Exception e) {e.printstacktrace ();} Weakreference///////////////////////////////////try {System.out.println (). Weakref.get (). GetName ());} catch (Exception e) {e.printstacktrace ();}
Zhangsanlisi
As seen from the execution results, even if the strong reference is broken at this time, it can still be referenced to the object in the head. In the absence of GC, SoftReference and weakrefenece have the same effect.
3. After the system GC
Softperson = Null;weakperson = null; System.GC ();////////////////////softrefernece////////////////////////////////////try {System.out.println ( Softref.get (). GetName ());} catch (Exception e) {e.printstacktrace ();} Weakreference///////////////////////////////////try {System.out.println (). Weakref.get (). GetName ());} catch (Exception e) {e.printstacktrace ();}
Java.lang.NullPointerExceptionzhangsanat Com.app.client.RefClient.main (refclient.java:49) at SUN.REFLECT.NATIVEMETHODACCESSORIMPL.INVOKE0 (Native Method) at Sun.reflect.NativeMethodAccessorImpl.invoke ( nativemethodaccessorimpl.java:57) at Sun.reflect.DelegatingMethodAccessorImpl.invoke ( delegatingmethodaccessorimpl.java:43) at Java.lang.reflect.Method.invoke (method.java:606) at Com.intellij.rt.execution.application.AppMain.main (appmain.java:140)
From the results, you can see that the object referenced by WeakReference in the head is garbage collected after the garbage collection mechanism is running, but the object that softreference references in the head still exists. when is the object referenced by the SoftReference being recycled? It will only be recycled if the memory is very small.
As can be seen from the above example: ? ? Strong citation "SoftReference >weakreference.
The following is the use of the Phatomrefernece class, which is the most different from the other two references is to add the reference to the reference queue, and then reclaim the object in the head, so we can in the reference queue to monitor the GC is about to be recycled objects.
Public class phatomrefclient { public static void main ( String[] args) { Person p = new Person (); p.setid (1); p.setname ("Zhaosi"); p.setage (+); &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;SYSTEM.OUT.PRINTLN (P); Referencequeue<person> queue = new referencequeue<person> (); phantomreference<person> pharef = new phantomreference <Person> (P, queue); p = null; &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;SYSTEM.GC (); while (True) { object o = queue.poll (); if (O != null) { try { Field rereferent = Reference.class .getdeclaredfield ("referent"); Rereferent.setaccessible (True); person result = (person) rereferent.get (o); system.out.println ("system gc will Kill person: " +result.getname ()); &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;SYSTEM.OUT.PRINTLN (Result); } catch (Exception e) { e.printstacktrace (); } } } }}
[Email Protected]system GC would kill Person:zhaosi[email protected]
Implement a simple caching system
public class personcache { private hashtable<integer, Personref> mcache = null; private referencequeue<person> queue; private static PersonCache instance; private personcache () { mcache = new Hashtable<Integer, PersonRef> ( queue =); new ReferenceQueue<Person> (); } public Static personcache getinstance () { if ( Instance == null) { Instance = new personcache (); } retuRn instance; } public void cacheperson (person p) { int id = p.getid (); personref ref = new personref (P, queue); mcache.put (ID,&NBSP;REF); } public person getpersonbyid (Int id) { Person p = null; p = (personref ) mcache.get (ID)). Get (); if (p == null) { mcache.remove (ID); clearcache (); p = new person (ID); system.out.println ("Create a new person"); cacheperson (P); } return p; } private void clearcache () { while (Queue.poll () != null) ; } //inside a _key class PersonRef extends WeakReference<Person> { int _key; public Personref (person referent, referencequeue<? super person> q) { &nbsP; super (referent, q); _key = referent.getid (); } }}
Public class client { public static void main (String args[]) { person p1 = new person (); p1.setid (1); P1.setname ("Wahaha1"); p1.setage (a); person p2 = new person (); p2.setid (2); p2.setname ("Wahaha2"); p2.setage (; person ) P3 = new person (); p3.setid (3); p3.setname ("Wahaha3"); P3.setage (&NBSP;&NBSP;&NBSP;&NBSP;&N);Bsp; person p4 = new person (); p4.setid (4); p4.setname ("Wahaha4"); p4.setage (; personcache ) Pc = personcache.getinstance (); pc.cacheperson (p1); pc.cacheperson (p2); pc.cacheperson (p3); pc.cacheperson (p4); p1 = null; p2 = null; p3 = null; p4 = null; system.out.println ( Pc.getpersonbyid (1). GetName ()); system.out.println (Pc.getpersonbyid (2). GetName ()); system.out.println (Pc.getpersonbyid (3). GetName ()); system.out.println (Pc.getpersonbyid (4). GetName ()); }}
? ?
Wahaha1wahaha2wahaha3wahaha4
balalala~~
Weak reference soft references and virtual references in Java