1. Strong reference

2. Soft references

3. A weak reference

4. Virtual reference

5. Use scenarios for soft and weak references

1. Strong reference Strong reference is the most common object reference we write (Person Person = new Person();) Strong reference to an object, you can show that the object is still “alive”, the garbage collector will not touch the object, the most common references in JAVA is a strong reference, give a reference to an object assignment variables, the reference variable is a strong reference, when an object is a strong reference variable references, it is in a state of, It is not possible for the object to be recycled by the garbage collection mechanism, even if the object is never used in the future, and the JVM does not recycle it, so strong references are one of the main causes of Java memory leaks.

Note: For a normal object, if there are no other references, either the reference scope is passed or a strong reference is explicitly assigned to null. It is generally believed that it is ready for garbage collection.

When memory runs out, the JVM begins garbage collection. Strongly referenced objects will not be collected even if an OOM appears.

2. Soft references

If we write an object to a soft reference, then: if the memory is sufficient, do not recycle the object if the memory is insufficient

Soft references are often useful in memory-sensitive programs, such as caching.

We can demonstrate this with code:

First we introduce a class, SoftReference class: softreReference . References passed to this class will become soft references as follows:

        Object o1 = new Object();
        SoftReference<Object> softReference = new SoftReference(o1);

The first is if there is sufficient memory:

public static void softRefMemoryEnough() { Object o1 = new Object(); SoftReference<Object> softReference = new SoftReference(o1); Println (o1); println(o1); println(o1); System.out.println(softReference.get()); O1 = null; o1 = null; o1 = null; o1 = null; o1 = null; System.gc(); System.out.println(o1); System.out.println(softReference.get()); }

The running results are as follows:

As you can see, in the case of sufficient memory, the soft reference is not reclaimed.

Next, let’s see if an object will be reclaimed if it runs out of memory.

public static void softRefMemoryNotEnough() { Object o1 = new Object(); SoftReference<Object> softReference = new SoftReference(o1); System.out.println(o1); System.out.println(softReference.get()); o1 = null; System.gc(); try { byte[] bytes = new byte[85 * 1024 * 1024]; } catch (Throwable e) { e.printStackTrace(); } finally { System.out.println(o1); System.out.println(softReference.get()); }}
public static void softRefMemoryNotEnough() { Object o1 = new Object(); SoftReference<Object> softReference = new SoftReference(o1); System.out.println(o1); System.out.println(softReference.get()); o1 = null; System.gc(); Byte [] bytes = new Byte [85 * 1024 * 1024]; Byte [] bytes = new Byte [85 * 1024 * 1024]; } catch (Throwable e) { e.printStackTrace(); } finally { System.out.println(o1); System.out.println(softReference.get()); }}

The running results are as follows:

As you can see, the soft reference object is reclaimed.

3. Weak references are recycled regardless of whether the memory is sufficient or not.

public static void weakRefMemoryEnough() { Object o1 = new Object(); WeakReference<Object WeakReference<Object WeakReference = new WeakReference(O1); System.out.println(o1); System.out.println(weakReference.get()); o1 = null; System.gc(); System.out.println(o1); System.out.println(weakReference.get()); }

The running results are as follows:



As you can see, both objects are reclaimed

Phantom reference is a more abstract concept:

First, the PhantomReference is implemented by the PhantomReference class

Fake references, as the name implies, do not determine the life of an object, unlike the other references. If an object only holds a dummy reference, then it is as likely to be collected by the garbage collector at any time as if it had no reference at all. It cannot be used on its own or accessed through it. The dummy reference must be used in conjunction with the reference queue.

The main purpose of a virtual reference is to keep track of the status of an object being garbage collected, but it simply provides a mechanism to make sure that an object does something once it has been Finalize. PhantomReference’s get method always returns null, so it cannot access the corresponding reference object. This means that an object has entered the Finalization phase and can be collected by GC to achieve more flexible collection operations than the Finalization mechanism.

In other words, the sole purpose of setting a virtual reference is to receive a system notification when the object is collected by the collector or to add further processing. Java technology allows you to use the finalize() method to do the necessary cleanup before the garbage collector clears the object from memory.

In other words, a dummy reference needs to be used with the reference queue, and it will appear in the reference queue once the dummy reference is reclaimed.

Let’s demonstrate this with code:

Object o1 = new Object(); // ReferenceQueue<Object> queue = new ReferenceQueue<>(); // PhantomReference<Object> Reference = new PhantomReference<>(o1, queue); System.out.println(o1); System.out.println(reference.get()); // The reference queue is empty System.out.println(queue.poll()); System.out.println("================"); o1 = null; System.gc(); Thread.sleep(500); System.out.println(o1); System.out.println(reference.get()); System.out.println(queue.poll());

The running results are as follows:

5. Use scenarios for soft and weak references:

If you have an application that needs to read a large number of local images, the performance will be severely affected if the images are read from the hard disk every time. If you load all the images into memory at once, you may run out of memory. Use a HashMap to store the map between the path of the image and the associated soft references of the corresponding image objects. When memory runs out, the JVM automatically reuses the space taken up by the cached image objects, thus effectively avoiding the problem of OOM.