Reference
Objects encapsulate references to other objects, operate as normal objects, and support the interaction with the garbage collector under certain constraints. That is, you can use the Reference object to refer to other objects, but it will eventually be reclaimed by the garbage collector. The program also sometimes needs to be notified after the object is recycled to inform the object that the accessibility has changed.
Java provides four different types of references, from high to low, respectively, toFinalReference
,SoftReference
,WeakReference
,PhantomReference
。 whichFinalReference
Not available for external use. Each of these types corresponds to different levels of accessibility.
Introduction to Strong references
FinalReference
A strong reference refers to a directly accessible reference in the program, without the need to pass any reference object, such as Object obj = new Object (), and obj as a strong reference.
Soft references
SoftReference
Soft references, non-strong references, but can be accessed through soft reference objects. Soft-referenced objects, the garbage collector decides to reclaim the object pointed to by the soft reference only when the memory is low (before the Oom exception is thrown). Soft references are typically used to implement memory-sensitive caches.
softreference<object> softref = new softreference<object> (new Object ());
Weak references
WeakReference
Weak references, non-strong references, and soft references, but can be accessed through weak reference objects. Weakly referenced objects, regardless of whether the memory is sufficient, as long as the garbage collector finds that the referenced object is recycled. The actual application see WeakHashMap
and so on.
weakreference<object> weakRef = new weakreference<object> (new Object ());
Virtual reference
PhantomReference
A virtual reference, which must be used in conjunction with the reference queue ( ReferenceQueue
), which is typically used to implement the garbage collector's recovery actions, such as when an object is recycled, the Finalize method of the object is invoked, and the action is made more secure by using a virtual reference.
Object obj = new Object (); referencequeue<object> refqueue = new referencequeue<> (); phantomreference<object> Phantom = new phantomreference<object> (obj, refqueue);
Referencequeue
This queue, as a member of the reference, can be combined with the above three reference types, which are used to register the queue to reference when the reference is created, and when the object referenced by the reference is reclaimed by the garbage collector. The reference is placed in the queue, which is equivalent to a notification mechanism.
Example DEMO1:
Referencequeue queue = new Referencequeue (); WeakReference reference = new WeakReference (new Object (), queue); SYSTEM.OUT.PRINTLN (reference); System.GC (); Reference Reference1 = Queue.remove (); System.out.println (Reference1);
SOURCE Analysis
Reference
And
ReferenceQueue
reference
has several more important properties inside
To save the reference to the object, the GC will take special care of the private T referent;//according to different reference if a notification mechanism is required, the corresponding queue referencequeue< is saved;? Super T> queue;/* This is used to implement a one-way loop linked list that will save references that need to be handled by Referencehandler */reference next;static Private class Lock {};//lock for the same Step pending queue incoming and outbound private static lock lock = new lock ();//This property holds a pending queue, with the above next using private static Reference pending = Null
State diagram
650) this.width=650; "Src=" http://images2015.cnblogs.com/blog/775325/201703/775325-20170319152438448-1930504798. JPG "style=" border:0px;height:auto;margin:0px;padding:0px; "/>
Inner class
ReferenceHandler
ReferenceHandler
As a static inner class of reference, used to implement the pending queueReference
Instances are added in turn to differentReferenceQueue
(depending on the queue within the reference). The element of the pending is added by the GC.
Note: The pending queue is locked, personally, because the GC thread may be executing concurrently with the thread that the Referencehandler is on, such as when the GC is being collected concurrently by the CMS.
As shown in the following code
This thread is started in a static block, that is, once reference is used, the thread is started Private static class referencehandler extends thread { public void run () { for (;;) { Reference r; synchronized (Lock) { if (pending != NULL) { r = pending; Reference rn = r.next; // takes the next element from the pending, and if the successor is empty, then next points to itself pending = (Rn == r) ? null : rn; r.next = r; } else { try { // no wait, subsequent join elements invoke lock.notify wake-up lock.wait (); } catch ( INTERRUPTEDEXCEPTION&NBSP;X) { } continue; } } // ... ReferenceQueue q = r.queue; // If the reference registers the corresponding queue, Add to the queue if (q != Referencequeue.null) q.enqueue (R); } }}
Referencequeue Property
Used to identify not registered queuestatic referencequeue NULL = new null ()//used to identify already in the corresponding queue in static referencequeue enqueued = new null (); St Atic Private class Lock {};/* Mutex for synchronizing the Remove and poll of Referencehandler Enqueue and user thread operations */private lock lock = new lock ();// Queue private volatile reference<? Extends t> head = null;//number of elements in the queue private long queuelength = 0;
Referencequeue.enqueue
This method will only be called through reference to put reference into the current queue
Boolean enqueue (Reference<? extends t> r) { synchronized (r) { // determine if you are already on the queue if (r.queue == enqueued) return false; synchronized (Lock) { r.queue = ENQUEUED; // Unidirectional Circulation r.next = (head == null) ? r : head; head = r; queuelength++; if (R&NBSP;INSTANCEOF&NBSP;FINALReference) { sun.misc.vm.addfinalrefcount (1); } // notifies the currently suspended thread (may hang when remove is called) lock.notifyall (); return true; } }}
Referencequeue.remove
Public reference<? extends t> remove (long timeout) throws illegalargumentexception, interruptedexception{ if (timeout < 0) { throw new IllegalArgumentException ("Negative timeout value"); } synchronized (lock) { // Remove an element from a queue reference<? extends t> r = reallypoll (); // if not empty, return directly to if (r != null) return r; for (;;) { // Otherwise wait, wake up by Enqueue when notify &nBsp; lock.wait (timeout); r = reallypoll (); if (r != null) return r; if (timeout != 0) return null; } }}
Specific implementation process
Using the example Demo1 above as an analysis
Create a reference queue Referencequeue queue = new Referencequeue ();//Create a virtual reference, at which time the state is active, and reference.pending is empty, the current reference.queue = The queue created above and next=nullweakreference reference = new WeakReference (new Object (), queue); SYSTEM.OUT.PRINTLN (reference);//When the GC is executed, because it is a virtual reference, the object is recycled and placed on pending, at which time the reference state is PENDINGSYSTEM.GC ();/* Referencehandler removes the element from the pending and puts the element into the queue, at which point the Reference state is Enqueued,reference.queue = referenceenqueued *//* When the element is removed from the queue, it becomes inactive,reference.queue = reference.null */reference Reference1 = Queue.remove (); System.out.println (Reference1);
Application-Weakhashmap
Weakhashmap in use and HashMap type, are hash + list to resolve the conflict, the only difference is that the former key is to use virtual reference to achieve, that is, when the garbage collection, is to be recycled, at this time Weakhashmap will be in the next operation, Remove from the map based on the key that was recovered.
Entry
When the entry is created, it is registered into the queue of the current map attribute, and when the key is recycled, the entry is placed into the queue, and the original value is erased whenever the map is manipulated. (It is done by the Expungestaleentries method and does not start a separate thread to handle, it is not necessary to simplify the logic and avoid the overhead of locking)
External Weakhashmap Properties private final referencequeue<object> queue = new Referencequeue<> ();/* uses integrated weakreference instead of direct use, because when it is recycled, the specific key is not known, there is a need to add some additional attributes to the WeakReference To be able to locate specific key/value */private static class entry<k,v> extends when notified after being recycled weakreference<object> implements map.entry<k,v> { // The attribute cannot be added to the key, or it will cause a strong reference and cannot be considered weakreference recycled v value; int hash; Entry<K,V> next; Entry (object key, v value, referencequeue<object> queue, int Hash, entry<k,v> next) { super (key, queue); this.value = value; this.hash = hash; this.next = NEXT;&NBSP;&NBSP;&NBSP;&NBSP;}&NBSP;&NBSP;&NBSP;&NBSP;//&NBSP, ...}
Java Reference Source Code Analysis