Four kinds of reference types in Java strong, Soft, Weak and Phantom__java

Source: Internet
Author: User
Tags garbage collection null null

Preface

As is known to all, Java is different from C + +, it does not require the programmer to manage memory (allocation, free memory), Java will manage memory itself, such as destroying some objects that are no longer in use. These actions are performed silently in a background thread (garbage Collector thread), which is the garbage collector thread that frees object memory based on the policies implemented by the JVM. But the program writer has no control over this background thread, can't let it start releasing memory when you want, destroy objects, destroy those objects according to your rules, release memory, these are all controlled by the JVM itself. But with the introduction of the classes under the Java.lang.ref package, programmers have a little bit of control over when the objects you create are released, destroyed, and of course just a little. Then let's look at the correspondence between these classes and the four types of references in Java. Take a look at these four types of references, because the JVM needs to determine which objects need to be destroyed when it is garbage collected, and then it is related to these types of references.

Here are the types of references: 1. Strong references (strong References)

Strong reference type is the most commonly used reference when we write code, and most people tend to ignore the concept, which is a matter of course.
Let's take a look at the following simple example:

public class Main {public


    static void Main (string[] args) {

        //Create an object, new objects are assigned to the Java heap of
        sample sample = NE W Sample ();   This reference to sample is a strong reference to

        sample = null;                  Point this reference to a null pointer,
                                        //Then the new object above is not pointing to it with any other valid reference//
                                        /It is also said that the object is eligible for the garbage collector//
                                        so at the next point in time the GC collects the action, The object will be destroyed, memory freed

    }

}

class Sample {

}

You can also draw a simple diagram to understand:
2. Soft reference (Soft References)

Soft references have the corresponding class java.lang.ref.SoftReference in the Java.lang.ref package.
Important: objects that are pointed to by a weak reference are not collected by the garbage collector (even if the object does not have a strong reference to it), the object is destroyed and the memory is freed unless the JVM uses enough memory. For a simple example:

public class Main {public

    static void Main (string[] args) {

        //Create an object, new objects are assigned to the Java heap of
        sample sample = NE W Sample ();   Sample This reference is strong reference

        //Create a soft reference point to this object   then there are two references to the sample object
        softreference<sample> softref = new Softreference<sample> (Sample);

        Point a strong reference to a null pointer there is only one soft reference pointing to the sample object
        //Note: Softref This reference is also a strong reference, which points to the object of SoftReference
        //So where is the soft reference. Can follow the java.lang.Reference source 
        //private T referent; This is the soft reference, only by the JVM using
        sample = NULL;

        You can regain the sample object and point to it with a strong reference to
        sample = Softref.get ();
    }

}

Class Sample {

}

Interested can go to see the source code of reference.

It is now possible to think of a use scenario for a soft reference, which avoids oom compared with strong references.

It is now easy to test the recovery of soft references when the JVM is low on memory.
To see the results faster, I limit the JVM's maximum heap memory-xmx100m to 100m

public class Main {private static final list<object> Test_data = new linkedlist<> ();  public static void Main (string[] args) throws Interruptedexception {//Create an object, new objects are assigned to the Java heap in the Sample   Sample = new sample (); Sample This reference is a strong reference//create a soft reference point to this object then there are two references to the sample object softreference<sample> softref = new Softre

        Ference<sample> (Sample); Point a strong reference to a null pointer there is only one soft reference pointing to the sample object//Note: Softref This reference is also a strong reference, which points to the object of SoftReference//So where is the soft reference? Can follow the java.lang.Reference source//private T referent;

        This is the soft reference, only the JVM uses sample = NULL;

        You can regain the sample object and point to it with a strong reference//sample = Softref.get (); New Thread () {@Override public void run () {while (true) {Sys
                    Tem.out.println (Softref.get ());
                    try {thread.sleep (1000);
               catch (Interruptedexception e) {         E.printstacktrace ();
                } test_data.add (New byte[1024 * 1024 * 5]);

        }}.start ();
    Thread.CurrentThread (). join ();

    Class Sample {Private final byte[] data;
    Public Sample () {data = new byte[1024 * 1024 * 10]; }
}

Run output results:

Example. sample@3f580216
Example. sample@3f580216
Example. sample@3f580216
Example. sample@3f580216
Example. sample@3f580216
Example. sample@3f580216
Example. sample@3f580216
null
null
Exception in thread ' Thread-0 ' Java.lang.OutOfMemoryError:Java heap
    space at example. Main$1.run (main.java:42)

You can see that when the JVM runs out of memory, the weakly referenced object is recycled 10m of the example above, and can be allocated two times 5m at a time, outputting two times null also proves this

Of course, when we create soft references, we can also pass in the Referencequeue, what's the use of this queue? When the JVM reclaims a soft reference object, the SoftReference object (the Softref object in the example) is added to the queue, so we know when the object is recycled and we can do what we want.

Public SoftReference (T referent, referencequeue< super t> Q) {
        super (referent, q);
        This.timestamp = clock;
}

Reference (T referent, referencequeue< Super t> queue) {
        this.referent = referent;
        This.queue = (queue = null)? ReferenceQueue.NULL:queue;
}

Let's give you a simple example.

public class Main {private static final list<object> Test_data = new linkedlist<> ();


    private static final referencequeue<sample> QUEUE = new referencequeue<> ();   public static void Main (string[] args) {//Create an object, new objects are assigned in the Java heap of sample sample = new sample (); Sample This reference is a strong reference//create a soft reference point to this object then there are two references to the sample object softreference<sample> softref = new Softre

        Ference<sample> (Sample, QUEUE); Point a strong reference to a null pointer there is only one soft reference pointing to the sample object//Note: Softref This reference is also a strong reference, which points to the object of SoftReference//So where is the soft reference? Can follow the java.lang.Reference source//private T referent;

        This is the soft reference, only the JVM uses sample = NULL;

        You can regain the sample object and point to it with a strong reference//sample = Softref.get (); New Thread () {@Override public void run () {while (true) {Sys
                    Tem.out.println (Softref.get ()); try {thread.sleep (1000);
                        catch (Interruptedexception e) {e.printstacktrace ();
                    Thread.CurrentThread (). interrupt ();
                } test_data.add (New byte[1024 * 1024 * 5]);

        }}.start (); New Thread () {@Override public void run () {while (true) {Ref erence<?
                    Extends sample> poll = Queue.poll ();
                        If (poll!= null) {SYSTEM.OUT.PRINTLN ("---Soft reference object is recycled by the JVM----" + poll);
                    SYSTEM.OUT.PRINTLN ("---recycled object----" + poll.get ());

        }}}.start ();
        try {thread.currentthread (). join ();
        catch (Interruptedexception e) {system.exit (1);

    }} class Sample {Private final byte[] data; Public Sample () {data = new byte[1024 * 1024 * 10]; }
}

Run output results:

Example. sample@2a3c142c
Example. sample@2a3c142c
Example. sample@2a3c142c
Example. sample@2a3c142c
Example. sample@2a3c142c
Example. sample@2a3c142c
Example. sample@2a3c142c
---Soft reference object was reclaimed by the JVM----java.lang.ref.softreference@306d3b64
null
---Reclaimed object----null
Null
Exception in thread "Thread-0" Java.lang.OutOfMemoryError:Java heap spaces at
    example. Main$1.run (main.java:47)
3. Weak references (Weak References)

Weak references are ignored by the JVM, which means that when GC does garbage collection, if an object has only a weak reference to it, then the JVM will destroy it decisively and free up memory if it has the same effect as no reference to it. In fact, this feature is very useful, the JDK also provides a java.util.WeakHashMap such a key for weak reference map. For example, a resource object you want to release (such as DB connection), but if the other map as a strong reference to the key, it can not be freed, by the JVM collection.

Here's a simple example:

public class Main {private static final list<object> Test_data = new linkedlist<> ();


    private static final referencequeue<sample> QUEUE = new referencequeue<> ();   public static void Main (string[] args) {//Create an object, new objects are assigned in the Java heap of sample sample = new sample (); Sample This reference is a strong reference//create a weak reference point to this object then there are two references to the sample object//softreference<sample> softref = new Soft
        Reference<sample> (Sample, QUEUE);
        weakreference<sample> weakref = new Weakreference<sample> (Sample, QUEUE); Point a strong reference to a null pointer there is only one weak reference pointing to the sample object//Note: Softref This reference is also a strong reference, which points to the object of SoftReference//So where is the weak reference. Can follow the java.lang.Reference source//private T referent;

        This is a weak reference, used only by the JVM sample = null;

        You can regain the sample object and point to it with a strong reference//sample = Softref.get (); New Thread () {@Override public void run () {while (true) {Sys Tem.oUt.println (Weakref.get ());
                    try {thread.sleep (1000);
                        catch (Interruptedexception e) {e.printstacktrace ();
                    Thread.CurrentThread (). interrupt ();
                } test_data.add (New byte[1024 * 1024 * 5]);

        }}.start (); New Thread () {@Override public void run () {while (true) {Ref erence<?
                    Extends sample> poll = Queue.poll ();
                        If (poll!= null) {SYSTEM.OUT.PRINTLN ("---weakly referenced object is recycled by the JVM----" + poll);
                    SYSTEM.OUT.PRINTLN ("---recycled object----" + poll.get ());

        }}}.start ();
        try {thread.currentthread (). join ();
        catch (Interruptedexception e) {system.exit (1); }} class Sample {Private final byte[] data;
    Public Sample () {data = new byte[1024 * 1024 * 10]; }
}

Run output results:

Example. Sample@234c0f50
Example. SAMPLE@234C0F50
---Weak reference object was reclaimed by the JVM----java.lang.ref.weakreference@16fea746
---Reclaimed object----null
null
Null
-NULL
-null-null-NULL
-null Exception in
thread ' Thread-0 ' Java.lang.OutOfMemoryError: Java Heap space at
    example. Main$1.run (main.java:47)

It is clear from the results that weakly referenced objects do not need to be recycled without the JVM running out of memory, and can be recycled at any time. 4. Illusory reference (Phantom References)

Illusory applications and weak-cited recycling mechanisms are similar, can be recycled at any time. But the difference is that its construction method must force the incoming referencequeue, because before the JVM is reclaimed ( emphasis: Yes, before recycling, soft and weak references are recycled ), The Phantomreference object will be added to the referencequeue; Another point is that the Phantomreference.get () method always returns empty, regardless of whether the object has been reclaimed.

Source: java.lang.ref.PhantomReference
    /**
     * Returns This Reference object ' s referent.  Because the referent of a
     * Phantom reference is always inaccessible, this method always returns
     * <code>nul L</code>.
     *
     * @return  <code>null</code>
    /public T get () {return
        null;
    }

Take an example to see:

public class Main {private static final list<object> Test_data = new linkedlist<> ();


    private static final referencequeue<sample> QUEUE = new referencequeue<> ();

        public static void Main (string[] args {Sample sample = new sample ();
        phantomreference<sample> phantomref = new Phantomreference<> (Sample, QUEUE);

        Sample = NULL; New Thread () {@Override public void run () {while (true) {Sys
                    Tem.out.println (Phantomref.get ());
                    try {thread.sleep (1000);
                        catch (Interruptedexception e) {e.printstacktrace ();
                    Thread.CurrentThread (). interrupt ();
                } test_data.add (New byte[1024 * 1024 * 5]);

        }}.start (); New Thread () {@Override public voID run () {while (true) {reference< extends sample> poll = Queue.poll ();
                        If (poll!= null) {SYSTEM.OUT.PRINTLN ("---Unreal reference object is recycled by the JVM----" + poll);
                        System.out.println (poll.isenqueued ());
                    SYSTEM.OUT.PRINTLN ("---recycled object----" + poll.get ());

        }}}.start ();
        try {thread.currentthread (). join ();
        catch (Interruptedexception e) {system.exit (1);

    }} class Sample {Private final byte[] data;
    Public Sample () {data = new byte[1024 * 1024 * 10]; }
}

Run Result:

NULL
NULL
---Illusory Reference object was reclaimed by the JVM----java.lang.ref.phantomreference@40788638
false
---Reclaim object----NULL NULL-null NULL NULL

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.