Weak reference soft references and virtual references in Java

Source: Internet
Author: User

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&LT;?&NBSP;SUPER&NBSP;T&GT;&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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.