Java Strong Reference|Soft Reference|Weak Reference|Virtual Reference

Keywords: Java jvm JDK

Due to the existence of GC auto-recycling mechanism in Java, the mechanism of reference counting is relatively perfect. Java divides the references of holding objects into strong references, soft references, weak references, virtual references in order of strength and weakness. Good use of references allows GC to quickly recycle instances that have exceeded its life cycle, thus putting the memory consumption of the machine at a low dynamic level and using them improperly.There will be a memory leak, which will cause the machine to run out of memory and shut down. We need to have a clear control over the characteristics of the programs we write. To keep the programs in a controlled state, at least as currently considered controllable.Now let's look at the classification of references before exploring the scenarios used.

1. Strong References

We usually use strong references, such as:

Map<String, Object> param = new HashMap<String, Object>(16); 

As mentioned above, references are strong references. As long as references are still in their valid lifecycle, GC cannot reclaim space on the heap corresponding to them. Of course, references themselves cannot be reclaimed. The use and rules of strong references are self-evident.

2. Soft References

First, let's look at how soft references are used:

Map<String, Object> param = new HashMap<String, Object>(16);
param.put("status", 1);
SoftReference<Map<String, Object>> softRef = new SoftReference<Map<String, Object>>(param);
System.out.println(softRef.get().get("status"));

There is more than one level of usage, but it's also understandable that soft references are only inferior to strong references. Only when the virtual machine thinks memory is insufficient, soft references are forced to reclaim the heap space they point to even during the lifetime. Calling get() then returns null, so normally, soft references do not behave as strong as strong references.Soft references are only characteristic of virtual machines when they think they are running out of memory.

3. Weak References

Use of weak references:

Map<String, Object> param = new HashMap<String, Object>(16);
param.put("status", 1);
WeakReference<Map<String, Object>> weakRef = new WeakReference<Map<String, Object>>(param);
System.out.println(weakRef.get().get("status"));

Weak references are used in almost the same way as soft references. They are a reference whose strength is inferior to soft references. References to instances by weak references are not counted by the reference counter. So if an instance does not have strong references and only weak references exist, it is possible for him to return null, depending on whether the GC recycles or not. There are both strong references and weak references in the above examples.Let's look at the case where only weak references exist:

WeakReference<Map<String, Object>> weakRef = new WeakReference<Map<String, Object>>(new HashMap<String, Object>(16));
System.gc();
System.out.println(weakRef.get());

null when printing, that is, weak references are not valid for GC's reference technology. Be aware of this feature when using it.

4. Virtual References

Virtual references are used slightly differently than above, and when the GC is ready to recycle an object, if it finds that it has any other virtual references, it adds them to the reference queue associated with it.An in-depth understanding of Java virtual machines: Advanced JVM features and best practices, second edition, subsection 3.2.3, states, "Virtual references, also known as ghost or phantom references, are the weakest kind of reference relationship.Whether or not an object has a virtual reference does not affect its lifetime at all, nor can it obtain an object instance through a virtual reference.The only purpose of setting a virtual reference Association for an object is to receive a system notification when the object is recycled by the collector.After JDK 1.2, the PhantomReference class was provided to implement virtual references"

Let's first look at the definition of virtual reference types:

public class PhantomReference<T> extends Reference<T> {

    public T get() {
        return null;
    }

    public PhantomReference(T referent, ReferenceQueue<? super T> q) {
        super(referent, q);
    }

}

We see that he has only one constructor and wants to specify a reference queue. The code below shows a Demo:

ReferenceQueue<Map<String, Object>> q = new ReferenceQueue<Map<String, Object>>();
PhantomReference<Map<String, Object>> phantomRef = new PhantomReference<Map<String, Object>>(new HashMap<String, Object>(16), q);
System.gc();
Thread.sleep(1000);
System.out.println(phantomRef.get());
System.out.println(q.poll());

The printed result is an instance of null and hantomReference, validating the fact that it is not possible to obtain an object instance through a virtual reference and that the reference is added to the reference queue.

Below we will discuss how these references are actually used.

Posted by weekenthe9 on Sun, 19 May 2019 09:22:04 -0700