Java Road Series: WEAKHASHMAP Implementation analysis

Source: Internet
Author: User

Give me a chestnut.

About the Reference object, the document of the Java.lang.ref package said a bunch, run up to see is the kingly,

publicclass Foo {    @Override    protectedvoidfinalizethrows Throwable {        System.out.println("finalize#"this);        super.finalize();    }}
    Private Staticreferencequeue<foo> queue =NewReferencequeue<foo> ();Static{NewThread (NewRunnable () {@Override             Public void Run() { while(true) {Reference ref =NULL;Try{ref = Queue.remove (); }Catch(Interruptedexception e)                    {E.printstacktrace (); } System.out.println ("removed#"+ ref);    }}). Start (); } Public Static void Main(string[] args)throwsexception{phantomreference<foo> PR = PR ();//Phantom reachableWeakreference<foo> WR = WR ();//weakly reachablesoftreference<foo> sr = sr ();//Softly reachableSystem.GC (); Thread.Sleep ( -); System.out.println ("pr.isenqueued () #"+pr.isenqueued ()); System.out.println ("Wr.get () #"+wr.get ()); System.out.println ("Sr.get () #"+sr.get ()); }Private StaticPhantomreference<foo>PR() {foo Foo =NewFoo (); phantomreference<foo> PR =NewPhantomreference<foo> (Foo, queue);returnOrd }Private StaticWeakreference<foo>WR() {foo Foo =NewFoo (); Weakreference<foo> WR =NewWeakreference<foo> (Foo, queue);returnwr }Private StaticSoftreference<foo>SR() {foo Foo =NewFoo (); softreference<foo> sr =NewSoftreference<foo> (Foo, queue);returnSr }

The output is like this,

removed#java.lang.ref.WeakReference@d48785finalize#[email protected]finalize#me.kisimple.just4fun.Foo@fdd15bpr.isEnqueued()#falsewr.get()#nullsr.get()#me.kisimple.just4fun.Foo@a0fbd6

Sometimes this is the case,

finalize#[email protected]finalize#[email protected]removed#[email protected]pr.isEnqueued()#falsewr.get()#nullsr.get()#[email protected]

finalize#removed#the order of the following is not fixed.
Below we will analyze the output according to the

The reachability of the referent have changed to the value corresponding to the type of the reference

, that is, the comment of the xxx reachable,referent and reference into the queue of the two operations.

Finalize
    • SoftReference, and will not be recycled. SoftReference will be kept in memory as long as possible, as long as it is not oom:)
    • WeakReference, will be recycled, finalize has been executed;
    • Phantomreference, will be recycled, finalize has been executed;
Enqueue
    • SoftReference, and did not enter the queue;
    • WeakReference, will enter the queue, the timing of the queue and finalize the order of execution is not fixed;
    • Phantomreference, also not into the queue;

But the API documentation says that

Some time after the garbage collector determines that the reachability of the referent have changed to the value correspond ing to the type of the reference, it'll add the reference to the associated queue.

But from the chestnut above only to see WeakReference behavior in accordance with the documentation, is there a bug or chestnut problems?

Memory leaks

About the WEAKHASHMAP,API documentation is described below,

More precisely, the presence of a mapping for a given key would not be prevent the key from being discarded by the garbage col Lector, that's, made finalizable, finalized, and then reclaimed. When a key have been discarded its entry are effectively removed from the map, so this class behaves somewhat differently fr Om other MAP implementations.

That is, even if Weakhashmap holds the key object does not prevent the key object from being recycled, it is equivalent to saying that Weakhashmap only holds a weakreference of the key object. When the key object is recycled, the corresponding mapping is also recycled. Look at the chestnuts below,

    Private Static  class Foo {        @Override        protected void Finalize()throwsThrowable {System.out.println ("finalize#"+ This);Super. Finalize (); }    }Private Static  class Bar {        Private LongId Public Bar(LongID) { This. id = ID; }@Override         Public Boolean equals(Object obj) {returnObjinstanceofBar? ((Bar) obj). id = = This. ID:false; }@Override         Public int hashcode() {return(int) (id ^ (ID >>> +)); }    }Private StaticMap<bar, object> sm =NewHashmap<bar, object> ();Private StaticMap<bar, object> wm =NewWeakhashmap<bar, object> (); Public Static void Main(string[] args)throwsexception{Strongmap ();        Weakmap ();        System.GC (); Thread.Sleep ( -); System.out.println (Sm.get (NewBar ( -))); System.out.println (Wm.get (NewBar (127))); }Private Static void Strongmap() {foo Foo =NewFoo (); Sm.put (NewBar ( -), foo); }Private Static void Weakmap() {foo Foo =NewFoo (); Wm.put (NewBar (127), foo); }

The output is as follows, the mapping of the weakhashmap is duly recycled, while the ordinary HashMap does not.

me.kisimple.just4fun.Main$Foo@2dce0null

Depending on this feature weakhashmap can be used instead of HashMap to prevent some memory leaks, refer to this document.

Weakhashmap

So how did the Weakhashmap come true? RTFSC,

    /** * 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;intHash Entry<k,v> Next;/** * Creates new entry. */Entry (Object key, V value, referencequeue<object> queue,intHash, entry<k,v> next) {Super(key, queue);//There is no need to have this.key = key; This is a line.             This. value = value; This. hash = hash; This. next = Next; }@SuppressWarnings("Unchecked") PublicKGetKey() {return(K) Weakhashmap.unmasknull (Get ()); } PublicVGetValue() {returnValue } PublicVSetValue(V newvalue)            {V OldValue = value; value = newvalue;returnOldValue; } Public Boolean equals(Object o) {...} Public int hashcode() {...} PublicStringtoString() {...} }

The biggest difference between a weakhashmap and a normal map is that this entry, which inherits WeakReference and has a sentence in its constructor, super(key, queue); so as we said above, Weakhashmap only holds a weak reference to a key object, and then simply queries the reference queue to queue know if the key object has been reclaimed, and if it is recycled, the entry will be erased, and the corresponding code in the expungeStaleEntries method

    /** * expunges stale entries from the table. */    Private void expungestaleentries() { for(Object x; (x = Queue.poll ()) = =NULL; ) {synchronized(queue) {@SuppressWarnings("Unchecked") entry<k,v> e = (entry<k,v>) x;inti = indexfor (E.hash, table.length);                Entry<k,v> prev = table[i]; entry<k,v> p = prev; while(P! =NULL) {entry<k,v> next = P.next;if(p = = e) {if(prev = = e) Table[i] = next;ElsePrev.next = Next;//must not null out e.next;                        //Stale entries May is in use by a hashiteratorE.value =NULL;//help GCsize--; Break;                    } prev = P;                p = Next; }            }        }    }

Most operations on Weakhashmap will call the method first getTable , and the method will first execute the method expungeStaleEntries to perform the above cleanup.

    /**     * Returns the table after first expunging stale entries.     */    privategetTable() {        expungeStaleEntries();        return table;    }

There is no need to start a thread specifically to poll the reference queue.

Resources
    • Http://docs.oracle.com/javase/8/docs/api/java/lang/ref/package-summary.html
    • Https://weblogs.java.net/blog/2006/05/04/understanding-weak-references
    • Plugging memory leaks with weak references
    • Plugging memory leaks with soft references

Java Road Series: WEAKHASHMAP Implementation analysis

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.