Java Weakhashmap Source Code parsing

Source: Internet
Author: User
Tags prev

The previous map based on a specific data structure, they use the corresponding data structure to achieve a special purpose, such as HashMap using a fast hash table to insert, find O(1) and delete the implementation of the change, treemap use the red and black trees to ensure the order of key at the same time, Make additions and deletions to change the time complexity of the search O(log(n)) .

The Weakhashmap to be introduced today is not based on a particular data structure, its main purpose is to optimize the JVM, so that the garbage collector in the JVM (garbage collector, followed by GC) more intelligent recycling of "useless" objects.

Reference type

WeakHashMapThe main difference from other maps is that its key is a weak reference type, and other map keys are strong reference types, and here it must be emphasized: in Java, there are four types of references: Strong (strong) references, soft (soft) references, weak (weak) references, Virtual (phantom, intended to be a ghost) is quoted. I believe that for Java beginners, not necessarily listen to these kinds of references similar, the following first describes the following types.

Strong references

This is the most commonly used reference type, and when you execute the following statement, the variable is o a strong reference.

Object o = new Object ();

The object that the strong reference points to is not cleaned by the GC at any time.

In general, for resident-class applications (such as server), the memory consumed tends to rise over time, and if the program uses strong references, it is easy to cause a memory leak, resulting in Out Of Memory (OOM) three other references in Java, except for strong references, all of which are located in java.lang.refpackage, described below.

Java.lang.ref.Reference

java.lang.ref.ReferenceThe parent class for soft (soft) references, weak (weak) references, and virtual (phantom) references.

Reference class inheritance Relationships

The following analysis Reference of the source code (the other three kinds of references are its subclasses, the distinction is not very large).

constructor function
Referent is the object that the reference points to reference (T referent) {This    (referent, null);} The Referencequeue object can be simply understood as a queue//gc after appropriate reachability changes is detected,//The Reference object itself is added to the queue. Easy to clean the reference object itself reference (T referent, referencequeue<? Super T> queue) {    this.referent = referent;    This.queue = (Queue = = null)? ReferenceQueue.NULL:queue;}

If we specify when we create a reference object, the ReferenceQueue GC will add the reference object itself to this queue when the object it refers to is in the appropriate state (depending on the reference type), so we can handle it because

The object that the reference object points to is automatically cleaned up by the GC, but the reference object itself is also an object (the object occupies a certain resource), so we need to clean it ourselves.

As an example:

softreference<string> ss = new softreference<string> ("ABC", queue);

ssAs a soft reference, pointing to abc this object, abc will be automatically cleaned up by GC at a certain time, but ss the cleanup work of the object itself depends on queue , when ss it appears in queue , the object that it points to is already invalid, can be relieved to clean ss up.

From the above analysis you should Reference have a basic understanding of the class, but also mentioned above, different references, added to ReferenceQueue the timing is not the same. The following is a description of the specific reference.
Here's a question: What happens if you create a reference object without specifying it ReferenceQueue ? There Reference are four states within the class that need to be understood.

Four different states

Each moment, the Reference object is in the following four states. These four states Reference are marked with a member queue variable next (similar to next in a single-linked list).

referencequeue<? Super t> queue; Reference Next;

Active. The newly created Reference object is this state, and when the GC detects that the reference object has reached the appropriate reachability, the GC makes state transitions based on whether the reference object was created, and if so, transfers to ReferenceQueue Pending , if not specified, to Inactive . In this state

If a queue is not specified in the construction parameter, then the queue is referencequeue.null, otherwise the Queuequeue = Referencequeue is passed in the construction parameter. Referencequeue.nullnext = null

Pending. The references in the Pending-reference list are in this state, and they are waiting to be processed by the internal thread ReferenceHandler (the method is called ReferenceQueue.enqueue ). Instances that are not registered will not enter this state. In this state

Queuequeue = Referencequeuenext = The next reference in the queue, if it is the last one in the

enqueued. The ReferenceQueue.enqueued reference after the calling method is in this state. Instances that are not registered will not enter this state. In this state

Queue = Referencequeue.enqueuednext = The next reference in the queue, if this is the last

Inactive. The final state, the referencing object in this state, does not change in state. In this state

Queue = Referencequeue.nullnext = This

With these constraints, the GC only needs to detect next the field to know if it needs to take special care of the Reference object

    • If it next is null , then the reference is Active state
    • If next not null , then the GC should process the reference in its normal logic.

My own according Reference.ReferenceHandler.run to ReferenceQueue.enqueue these two methods, draw out the four states of the transfer diagram for your reference:

Reference state transition diagram

To understand what this status GC does, it needs to look at the code of the JVM, and I don't have enough time or power here to caught dead, and then have the opportunity to pits.
For A typical programmer, these four states can be completely out of control. The last two sentences summarize the above four states:

    1. If specified in the constructor ReferenceQueue , then the programmer can then clean up the reference through the queue.
    2. If it is not specified in the constructor ReferenceQueue , the GC automatically cleans up the reference
Get

The calling Reference.get method can get the object that the reference points to, but because the object pointed to may be cleaned up by the GC at any time, even in the same thread, calls at different times may return distinct values.

Soft references (soft reference)

Soft references to "save" objects are less capable of mpfso references, but above weak references, and are generally used to implement memory-sensitive caches.

The object that the soft reference points to is cleared by the GC when the program is about to fire, and OOM then the reference object is dropped ReferenceQueue .

Weak references (weak reference)

Soft references to "save" objects are less capable than weak references, but higher than virtual references, which are generally used to implement canonicalizing mapping, which is what this article is about WeakHashMap .

When a weak reference is directed to an object that is accessible only through a weak reference (no strong or weak reference), the GC cleans up the object and then the reference object is dropped into the ReferenceQueue middle.

Virtual reference (Phantom Reference)

A virtual reference is the weakest reference to the "Save" object, and is generally used to implement scheduling Pre-mortem cleanup actions in a more flexible means than is possible with the Java Finali Zation mechanism

A method that calls a virtual reference get is always returned null , unlike a soft reference and a weak reference, when a virtual reference is enqueued not automatically cleaned out by a virtual reference, and only when all virtual references to the object have been cleaned (after enqueued) or are not self-reached. The object will not be cleaned up.

Weakhashmap.entry

The above introduces a lot of references to the knowledge point, in fact, WeakHashMap there is nothing to say, as long as the role of reference and use of the scene to clear, then to analyze the objects based on these references will be very simple.
WeakHashMapAs with HashMap the signature and the constructor, here is not introduced, here is the focus on the Entry internal object, because it saves the specific key-value pair, so it is clear, the other is not a big problem.

/** * The entries in this hash table extend WeakReference, using its main ref * field as the key. */private static Class Entry<k,v> extends Weakreference<object> implements map.entry<k,v> {V value     ;     int hash;     Entry<k,v> Next;      /** * Creates new entry.  */Entry (Object key, V value, referencequeue<object> queue, int hash, entry<k,v> next) {//Here the key is passed to the parent class WeakReference, stating that key is a weak reference (no explicit This.key = key)//All if key is only accessed by a weak reference, key will be cleaned by GC// The entry that the key represents is entered into the queue, waiting to be processed//You can also see that value is a strong reference (there is an explicit This.value = value), but this does not affect//can be seen after the Weakhashmap.expung         The Estaleentries method is how to clean up the value of super (key, queue);         This.value = value;         This.hash = hash;     This.next = Next;  } @SuppressWarnings ("Unchecked")//Must be unmasknull when acquiring key because the null key is the public K GetKey () represented by the internal member property of Weakhashmap     {return (K) weakhashmap.unmasknull (Get ()); } PublIC V GetValue () {return value;         Public V SetValue (v newvalue) {v oldValue = value;         value = newvalue;     return oldValue; } public boolean equals (Object o) {if (! (         o instanceof Map.entry)) return false;         map.entry<?,? > E = (map.entry<?,? >) o;         K K1 = GetKey ();         Object K2 = E.getkey (); if (k1 = = K2 | | (K1! = null && k1.equals (K2)))             {V V1 = GetValue ();             Object v2 = E.getvalue (); if (v1 = = V2 | |                 (V1! = null && v1.equals (v2)))         return true;     } return false;         } public int hashcode () {k k = GetKey ();         V v = getValue ();     Return ((K==null 0:k.hashcode ()) ^ (v==null? 0:v.hashcode ()));     } public String toString () {return GetKey () + "=" + GetValue (); } }
Weakhashmap.expungestaleentries
/** * Reference queue for cleared weakentries *///all entry are passed into the Queueprivate final referencequeue<object> queue at construction time = New Referencequeue<> ();/** * expunges stale entries from the table. */private void Expungestaleentries () {for (Object x; (x = Queue.poll ()) = null; {synchronized (queue) {//E is @SuppressWarnings for objects to be cleaned ("unchecked") ENTRY&L T            K,v> e = (entry<k,v>) x;            int i = indexfor (E.hash, table.length);            Entry<k,v> prev = table[i];            entry<k,v> p = prev;                While loop traversal conflict chain while (P! = null) {entry<k,v> next = P.next;                    if (p = = e) {if (prev = = e) Table[i] = next;                    else Prev.next = next;                    Must not null out e.next; Stale entries may is in use by a hashiterator//you can see that value is assigned toNull to help GC reclaim the strongly referenced value e.value = null;                    Help GC size--;                Break                } prev = P;            p = Next; }        }    }}

Knowing the expungeStaleEntries function of the method, let's see when it was called

Expungestaleentries Call Chain

As you can see, the WeakHashMap method is called when the add-and-revise is checked expungeStaleEntries .

Actual combat

It says, here's a concrete example to help you digest

Import Java.util.weakhashmap;class keyholder {@Override protected void Finalize () throws Throwable {System.        Out.println ("I am over from key");    Super.finalize (); }}class Valueholder {@Override protected void Finalize () throws Throwable {System.out.println ("I am over FR        Om value ");    Super.finalize (); }}public class Reftest {public static void main (string[] args) {weakhashmap<keyholder, valueholder> weak        Map = new Weakhashmap<keyholder, valueholder> ();            Keyholder kh = new Keyholder ();        Valueholder VH = new Valueholder ();        Weakmap.put (KH, VH); while (true) {Keyholder key:weakMap.keySet ()) {System.out.println (key + ":" + Weakmap            . Get (key));            } try {thread.sleep (2000);            } catch (Interruptedexception e) {e.printstacktrace ();            } System.out.println ("here ..."); The KH is set up hereIs null, so that only the weak reference points to the object that KH is pointing to kh = null;        System.GC (); }    }}

Output

[Email protected]: [Email protected]here ... I am over from key   //Output This sentence indicates that the key corresponding to the entry has been GC cleanup here...here...here ...
Summarize

To tell the truth, I did not know how to quote before, it is not used WeakHashMap This class, this is to fill the pit. Reference usage scenarios should be used in the resident class or consume large memory applications, I really did not experience this type of project, can only now lay a good foundation, and later have the opportunity to try.

In fact, on the reference, this article focuses on the use of weak reference scenarios, the other is not how to introduce, interested in reading the reference to the link given.

Java Weakhashmap Source Code parsing

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.