An overview,

As we all know, in Java, the JVM is responsible for memory allocation and reclamation, which is both its strength (ease of use, programs don’t have to worry about memory as much as they do with C) and its weakness (inflexible). In order to solve the problem of inflexible memory operation, soft reference and other methods can be used.

Prior to JDK1.2, when an object was not referenced by any variable, the program could no longer use the object. That is, a program can only use an object if it is in a touchable state. It is like buying something from a shop in everyday life and keeping it if it is useful or throwing it in the dustbin to be collected by the cleaners. Generally speaking, if an item has been thrown into the trash, it is impossible to pick it up and use it again.

But sometimes the situation is not so simple, you may encounter similar chicken ribs, food tasteless, it is a pity to discard. This item is now useless, keeping it takes up space, but it’s not worth it to throw it away now, because it may come in handy in the future. There’s a compromise: if you have enough space, keep it at home. If you don’t have enough space, even if you remove all your trash, you still can’t fit in those essential items, then throw them out.

Starting with JDK1.2, object references are divided into four levels, giving programs more flexibility in controlling the life cycle of objects. The four levels are in descending order: strong reference, soft reference, weak reference, and virtual reference. These four reference types are provided in Java for two main purposes: first, they allow programmers to determine the life cycle of certain objects in code; The second is to facilitate garbage collection by the JVM.

Second, the rounding

1. Strong references

Most of the references we used before were actually strong references, which are the most commonly used references. If an object has a strong reference, it is like an essential household item, and the garbage collector will never collect it. When running out of memory, the Java virtual machine would rather throw outofMemoryErrors to abort the program than randomly recycle objects with strong references to resolve the memory problem.

We can assign the object display value to NULL, and then gc will assume that there is no reference to the object, in which case the object can be reclaimed. Exactly when to collect depends on the GC algorithm. That is, there is a strong reference inside the method, which is stored on the stack, while the actual reference content (Object) is stored in the heap. When the method is finished, it exits the stack, the reference to the content does not exist, and the Object is reclaimed. However, if the object is a global variable, it needs to be null when the object is not used, because strong references are not garbage collected.

Let’s look at the clear method in Arraylist

/** * Removes all of the elements from this list. The list will * be empty after this call returns. */
    public void clear(a) {
        modCount++;

        // clear to let GC do its work
        for (int i = 0; i < size; i++)
            elementData[i] = null;

        size = 0;
    }
Copy the code

2. SoftReference

If an object has only soft references, it is similar to a living object that can have objects. If there is enough memory, the garbage collector will not reclaim it, and if there is not enough memory, it will reclaim the memory of these objects. As long as the garbage collector does not collect it, the object can be used by the program. Soft references can be used to implement memory sensitive caching. A soft reference can be used in conjunction with a ReferenceQueue (ReferenceQueue), and if the object referenced by the soft reference is garbage collected, the JAVA virtual machine adds the soft reference to the ReferenceQueue associated with it.

public class TestSoftReference {
    public static void main(String[] args) {
        System.out.println("start...");
        Object object = new Object();
        SoftReference<Object> sr = new SoftReference<Object>(object);
        object = null;
        if(sr ! =null) {
            object = sr.get();
            if (jvm.OutOfMemory()) { // When the JVM is out of memory
                object = null; // Convert to soft reference
                System.gc(); // The garbage collector collects}}else {
            object = new Object();
            sr = new SoftReference<Object>(object);
            System.out.println(sr); / / output object Java. Lang. Ref. D50c0 SoftReference @ 511
        }
        
        System.out.println(object); / / output is null
        System.out.println("end..."); }}class Object {
    int[] object;
    public Object(a) {
        object = new int[100000000]; }}Copy the code

3. WeakReference

If an object has only weak references, it is similar to a living object that can have objects. The difference between weak and soft references is that objects with only weak references have a shorter lifetime. When the garbage collector thread scans the memory area under its control, once it finds an object with only weak references, it reclaims its memory regardless of whether the current memory space is sufficient. However, because the garbage collector is a low-priority thread, objects that have only weak references are not necessarily found quickly.

Weak references can be used in conjunction with a ReferenceQueue (ReferenceQueue), and if the object referenced by a weak reference is garbage collected, the Java virtual machine adds the weak reference to the ReferenceQueue associated with it. Such as:

WeakReference<String> sr = new WeakReference<String>(new String("hello"));
System.out.println(sr.get());
System.gc(); // Manually emulate the JVM's GC for garbage collection
System.out.println(sr.get());
Copy the code

Result output:

hello

null

This means that whenever the JVM does garbage collection, objects associated with weak references are bound to be collected.

4. Virtual Reference

Unlike the other references, virtual references do not determine the life cycle of an object. If an object holds only virtual references, it can be garbage collected at any time, just as if there were no references at all.

Virtual references are mainly used to track the activity of objects being garbage collected. One difference between a virtual reference and a soft or weak reference is that a virtual reference must be used in conjunction with a ReferenceQueue. When the garbage collector is about to reclaim an object and finds that it has a virtual reference, it adds the virtual reference to the reference queue associated with it before reclaiming the object’s memory. A program can determine whether a referenced object is about to be garbage collected by determining whether a virtual reference has been added to the reference queue. If a program finds that a virtual reference has been added to the reference queue, it can take the necessary action before the memory of the referenced object is reclaimed.

In particular, weak references and virtual references are rarely used in the century programming, but soft references are used more, because soft references can speed up the recycling of garbage memory by JVM, maintain the safety of the system, and prevent memory overflow (OutOfMemory) and other problems.

		Object obj = new Object();
        ReferenceQueue<Object> rq = new ReferenceQueue<Object>();
        PhantomReference<Object> pf = new PhantomReference<Object>(obj,rq);
        obj=null;
        System.out.println(pf.get());// Always return null
        System.out.println(pf.isEnqueued());// Returns whether it has been deleted from memory
        System.gc();
        TimeUnit.SECONDS.sleep(6);
        System.out.println(pf.isEnqueued());
Copy the code

Result output:

null

false

true

Third, summary