preface

A thread pool thread exists all the time. Does using a ThreadLocal leak? So how do you do that? Why is that ok? What was the quote used? How does ThreadLocal work? “, the author has been asked this question many times, so I plan to systematically review, the foundation still needs to be solid, more hands-on practice, not just rely on watching and memorizing, only really use, know the principle, can slowly grow, refuse to only CRUD, from CRUD to think about the system, improve the code level to complete the transformation.

Soft references

SoftReference An object is modified. If the memory is insufficient, the object is reclaimed to prevent OOM occurrence

/ / example ImageCache. Class

The cache class is used to cache the main function of image resources, because the resources is very big, if memory can’t timely recovery, the resources object references, then the JVM is not recycling this part of the memory, then over time will be a memory leak, and soft references can be soft references before OOM recycling reference object, to a certain extent prevent OOM, In addition, ReferenceQueue will put the soft reference into the object before recycling, so that it can obtain some relevant information about the current operation. For example, ImageCache is used to store the Key, so that after recycling, it can obtain the Key from the soft reference, and then delete the Key from the map to prevent too many keys.

private final LinkedHashMap<ImageCache.PixelsKey, ImageCache.ImageSoftReference> map;  

private static class ImageSoftReference extends SoftReference<Image> {
        final ImageCache.PixelsKey key;

        ImageSoftReference(ImageCache.PixelsKey var1, Image var2, ReferenceQueue<? super Image> var3) {
            super(var2, var3);
            this.key = var1; }}Copy the code

Strong reference

Strong references should be the most used, as we usually instantiate objects, which is strong references

Object a = new Object();
Copy the code

If we want to reclaim an object, we need a = null to eliminate the strong reference of the object. However, whether the JVM will reclaim the object depends on the collection policy and whether the object is referenced by other objects.

As you can see in the source code of ArrayList, the remove method sets the reference of the last element to null, so that the element that was originally pointed to loses its strong reference, and this part of memory is reclaimed during the reachable analysis.

public E remove(int index) {
        rangeCheck(index);

        modCount++;
        E oldValue = elementData(index);

        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; // clear to let GC do its work

        return oldValue;
    }
Copy the code

A weak reference

WeakReference

Objects decorated with weak references are collected every time the garbage is collected, so that objects are not recycled after they have been used.

Let’s take a look at where weak references are used. ThreadLocal does a great job of isolating variables from each thread, preventing variable contamination and dirty reads from crossing threads. Let’s see how weak references are used in it.

static class ThreadLocalMap {
  
  static class Entry extends WeakReference<ThreadLocal<? >>{
            /** The value associated with this ThreadLocal. */Object value; Entry(ThreadLocal<? > k, Object v) {super(k); value = v; }}}Copy the code

This is decorated with weak references to variables of type ThreadLocal. Used for Entry in ThreadLocalMap. If a thread pool is used, we know that the core thread of the pool will not be destroyed unless shutdown is called. Then there is a problem: ThreadLocalMap -> Entry -> ThreaLocal’s reference chain always exists. So here using weak references for ThreadLocal, when no longer used can be timely recovery, if not timely recovery, can lead to memory leaks, was not soft references is soft references is when insufficient memory to recycling, and here we need is if you do not use should be recovered as soon as possible, because many high concurrent threads, need timely recovery, Soft references obviously don’t.

Phantom reference

PhantomReference

A virtual reference can be reclaimed at any time, just like no reference. It is usually used to track object collection, notify when an object is reclaimed, and so on

Let’s look at an example of virtual reference usage

public class ReferenceTest {
    public static void main(String[] args) {
        A a = new A();
        ReferenceQueue<A> queue = new ReferenceQueue<>();
        B<A> phantomReference = new B<>(a,queue,"Order Service");
        a = null;
        System.gc();
        System.out.println(phantomReference.get());
        System.out.println(((B)queue.poll()).taskName + "Recycled."); }}class A{}class B<A> extends PhantomReference<A>{
     final String taskName;
    public B(A referent, ReferenceQueue<? super A> q,String taskName) {
        super(referent, q);
        this.taskName = taskName; }}Copy the code

Above we track the collection process through the use of virtual references and record the collection objects.

The last

In the next article, I plan to introduce the principle of ThreadLocal in detail and analyze the source code with you. Source code is the essence of ThreadLocal.

Learning is like rowing upstream; not to advance is to drop back.