Deep understanding of 4 types of reference in Java

Source: Internet
Author: User

Brief introduction

First of all, you should know that Java has provided four reference types from 1.2, namely their references (strongreference), soft references (softreference), weak references (WeakReference), and Phantomreference ( Virtual references), they are ranked from large to small in the likelihood of GC recycling. Such as

You can see that reference is inherited from object, and there are three direct subclasses, that is, we are going to introduce several classes. There's another referencequeue, and I don't think anyone will know.

He was used to save a reference object that is about to be disposed, with the instance code below the specific user

Here is a separate introduction to each reference, and attached to the test code, to facilitate the deep understanding of everyone

Strongreference

Just like his name, any time the GC is not able to reclaim his, even if the memory is not enough, the system will directly throw an exception outofmemoryerror, will not be recycled, the first thing to say is that Java is the default is a strong reference, such as the following code:

new Persion();

where P is a strong reference and will not be recycled by GC at any time

/** * 测试强类型,可以看到我们调用多次gc他还是没有回收 */privatestaticvoidtestStrongReference() {    new Person("Jack");    System.gc();    System.gc();    System.out.println(jack);}
SoftReference

Soft references his feature is that when memory is sufficient, objects of this reference type are not recycled, and are recycled only when there is insufficient memory, a feature that is best suited for most caches, such as the cache of images in Android

/** * 测试软类型引用 */privatestaticvoidtestSoftReference() {    new Person("Jack");    new SoftReference<>(jack);    System.out.println(personSoftReference.get());    null;    System.gc();    System.gc();    System.out.println(personSoftReference.get());}

Output:

Person{name=‘Jack‘}Person{name=‘Jack‘}

You can see that although we have manually called the GC but the reference type has not been recycled

WeakReference

The feature of virtual references is that as long as the GC runs it will be recycled, and the personal feel is not much use, because as long as the GC runs he will be recycled '

privatestaticvoidtestWeakReference() {    new Person("Jack");    new WeakReference<Person>(jack);    System.out.println(personSoftReference.get());    System.gc();    System.gc();    System.out.println(personSoftReference.get());}

We run the code to find the object is still not recycled, because although we call the GC, this method only notifies him to execute, but what execution still depends on his mood. Of course, the above code has a very important reason is that the Jack object is a strong reference, so in how to invoke the GC he will not be recycled, why? Because Jack, the variable, he also strongly quoted the object, we gave him empty, in the call GC he was recycled, the following code:

privatestaticvoidtestWeakReference() {    new Person("Jack");    new WeakReference<Person>(jack);    System.out.println(personSoftReference.get());    null;    System.gc();    System.gc();    System.out.println(personSoftReference.get());}

Output:

Person{name=‘Jack‘}null

We can see the results, as we expected.

Phantomreference

A virtual reference does not have a reference to it, primarily to create this type of reference, then the reference type is recycled

privatestaticvoidtestPhantomReference() {    new Person("Jack");    new ReferenceQueue<>();    new PhantomReference<Person>(jack,personReferenceQueue);    System.out.println(personSoftReference.get());//        jack = null;//        System.gc();//        System.gc();    System.out.println(personSoftReference.get());}

Output:

nullnull

You can see that as soon as one is created, it is recycled directly.

Referencequeue

He is a reference to the column, you can monitor the reference object is recycled, specifically, when a reference object he refers to the value is recycled, then the system will add this reference to the column, the following code:

privatestaticvoidtestReferenceQueue() {    new Person("Jack");    new ReferenceQueue<>();    new WeakReference<Person>(jack, personReferenceQueue);    null;    System.gc();    System.out.println(personSoftReference.get());}

When the Jack object referenced by Personsoftreference is recycled, the system will add the Personsoftreference object to the Personreferencequeue, what exactly does it do, and imagine this scenario, A hashmap his key is a byte[] array, we need to create 10,000 such keys to add him to HashMap, which is if the machine's memory is small then he can be out of memory, but when we use a reference to wrap the key, Then add it to HashMap:

Private Static void testReferenceQueue1() {referencequeue<object> Weakreferencereferencequeue =NewReferencequeue<> ();intM1 =1024x768; Object o =NewObject (); map<weakreference<byte[]>, object> map =NewHashmap<> ();//Create a thread to listen for recycled objects    NewThread (NewRunnable () {@Override         Public void Run() {Try{intCNT =0; weakreference<byte[]> K; while((k = (weakreference) weakreferencereferencequeue.remove ())! =NULL) {System.out.println (cnt++) +"Recycle:"+ K +","+k.get ()); System.out.println ("Map.size:"+ map.size ()); }            }Catch(Interruptedexception e) {//End Loop}}). Start (); for(inti =0; I <10000; i++) {byte[] bytes =New byte[M1]; Map.put (NewWeakreference<> (bytes,weakreferencereferencequeue), O);    } System.GC (); System.out.println ("Map.size:"+ map.size ());}

Output:

...9997Recycle:java. Lang. Ref. WeakReference@2A62b5bc,nullmap.size:100009998Recycle:java. Lang. Ref. WeakReference@27E47833,nullmap.size:100009999Recycle:java. Lang. Ref. WeakReference@18E8473e,nullmap.size:10000

You can see that he recycles so many objects, because we return NULL when we call get (), but the problem is that the size of the map is still 10000, which is not what we expect, because the object that he refers to is looked back, and that map can be equivalent to a failure, What we want is to recycle the reference object, which means that the size of map becomes the size of the actual available object.

Private Static void testReferenceQueue2() {referencequeue<object> Weakreferencereferencequeue =NewReferencequeue<> ();intM1 =1024x768; Object o =NewObject (); map<weakreference<byte[]>, object> map =NewHashmap<> ();//Create a thread to listen for recycled objects    NewThread (NewRunnable () {@Override         Public void Run() {Try{intCNT =0; weakreference<byte[]> K; while((k = (weakreference) weakreferencereferencequeue.remove ())! =NULL) {Map.Remove (k);//Here we remove references to recycled objectsSystem.out.println ((cnt++) +"Recycle:"+ k); System.out.println ("Map.size:"+ map.size ()); }            }Catch(Interruptedexception e) {//End Loop}}). Start (); for(inti =0; I <10000; i++) {byte[] bytes =New byte[M1]; Map.put (NewWeakreference<> (bytes, weakreferencereferencequeue), O);    } System.GC (); System.out.println ("Map.size:"+ map.size ());}

Output:

9996Recycle:java. Lang. Ref. WeakReference@1608Bcbdmap.size:39997Recycle:java. Lang. Ref. WeakReference@777C9dc9map.size:29998Recycle:java. Lang. Ref. WeakReference@535779E4map.size:19999Recycle:java. Lang. Ref. WeakReference@6F6745d6map.size:0

You can see the object that was recycled, and we removed its key from the map.

Weakhashmap

His effect is similar to the above, when a key reference object is recycled, he will automatically remove the key

We loaded the list with even values in the table below so that he wouldn't be allowed to recycle those objects.

Private Static void Testweakhashmap() {referencequeue<object> Weakreferencereferencequeue =NewReferencequeue<> ();intM1 =1024x768; Object o =NewObject (); map<byte[], object> map =NewWeakhashmap<> (); arraylist<byte[]> bytes1 =NewArraylist<> (); for(inti =0; I <10000; i++) {byte[] bytes =New byte[M1];if(i%2==0) {Bytes1.add (bytes);        } map.put (bytes, o); bytes =NULL;    } System.GC (); System.out.println ("Map.size:"+ map.size ());}

Output:

map.size:5000

You can see that as we said above, he will remove the recovered key.

Reference: http://www.iflym.com/index.php/java-programe/201407140001.html

Deep understanding of 4 types of reference in Java

Related Article

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.