Reference types in JAVA, strong reference soft reference weak reference virtual reference

strong reference

Both are strong references. Strong references are most commonly used in development. As long as there are references to objects, they will not be recycled by GC

// 我们自己定义的实体通过直接new的形式都是强引用
Object obj = new Object();

soft reference

General objects will not be recycled. When the application memory is about to be exhausted -> when OOM is about to occur, the garbage processor will recycle it, which can prevent the application from being down and unavailable due to OOM.

SoftReference<String> ref = new SoftReference<String>("aaa");

weak quotation

When the root reference becomes invalid, it will be recycled when the GC is triggered next time. Even if the root reference is reassigned after recycling, the reference will not be re-established

In the process of scanning the memory area under its jurisdiction by the garbage collector thread, once an object with only weak references is found, its memory will be reclaimed regardless of whether the current memory space is sufficient or not.

WeakReference<String> ref = new WeakReference<String>("aaa");
示例
String str=new String("333");
WeakReference<String>ref=newWeakReference<>(str);
System.out.println(ref.get());
str=null;
System.out.println(ref.get());
System.gc(); // 手动触发一次gc
System.out.println(ref.get());

Result: 333 333 null

dummy reference

Virtual references are not real references and do not affect normal garbage collection.
When the garbage collector decides to recycle the PhantomReference object, it will insert it into the ReferenceQueue.

PhantomReference.class

public class PhantomReference<T> extends Reference<T> {
    
    
    public T get() {
    
    
        return null;
    }
    public PhantomReference(T referent, ReferenceQueue<? super T> q) {
    
    
        super(referent, q);
    }
}

For an object, this reference is useless, and it is the same as not having it. Phantom references must be used together with the reference queue. Its function is to track the garbage collection process and receive a system notification when the object is reclaimed by the collector. When the garbage collector is about to reclaim an object, if it finds that it still has a virtual reference, it will add this virtual reference to the reference queue after garbage collection, and will not completely destroy the object until its associated virtual reference is dequeued.

Virtual references are often ReferenceQueueused in conjunction with reference queues

reference queue

ReferenceQueue

ReferenceQueue can be used with SoftReference/WeakReference/PhantomReference

refrenceQueueIn essence, it is a linked list, which ensures synchronizedthread safety, maintains volatilethe modified headobject, represents the current head object, and maintains the current number of queues

Take a look at how thread safety issues are guaranteed

static private class Lock {
    
     };
private Lock lock = new Lock();

It can be seen that a global lock object is used here. This is an empty object, which exists only as a lock object. Its core is only to lock removemethods and enqueuemethods (join queue and remove queue)

synchronized(lock){
    
    
	// ...
}

When we call removea method, the method will be called to Object.waitblock, and when gc is triggered, enqueuenotifyAll will be called to notify the thread, which is not a cas operation, so it has little impact on performance

The following simulates a scenario. When our object is recycled by gc, the reference key in the map is removed.

public class Test {
    
    

    private static ReferenceQueue<byte[]> referenceQueue = new ReferenceQueue<>();
    private static int _1M = 1024 * 1024;

    public static void main(String[] args) throws InterruptedException {
    
    
        final Map<Object, MybObject> map = new HashMap<>();
        Thread thread = new Thread(() -> {
    
    
            try {
    
    
                int n = 0;
                MybObject k;
                while (null != (k = (MybObject) referenceQueue.remove())) {
    
    
                    // 每次触发gc都会进来一次
                    System.out.println("gc:" + (++n));
                    map.remove(k.key);
                }
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        });
        thread.setDaemon(true);
        thread.start();
				// 创建1000个对象放入map中
        for (int i = 0; i < 1000; i++) {
    
    
            byte[] bytesKey = new byte[_1M];
            byte[] bytesValue = new byte[_1M];
            map.put(bytesKey, new MybObject(bytesKey, bytesValue, referenceQueue));
        }
        Thread.currentThread().join();
    }

    static class MybObject extends PhantomReference<byte[]> {
    
    
        private Object key;

        MybObject(Object key, byte[] referent, ReferenceQueue<? super byte[]> q) {
    
    
            super(referent, q);
            this.key = key;
        }
    }
}

operation result

gc:1
gc:2
...
gc:792
gc:793
gc:794

It can be seen that there is no recycling until 794 is recovered here, and the remaining 206 objects are still in the heap memory and have not been released

Note: The result is not the same under all computers, it is related to the computer, configuration, and jvm parameters, and the results are different each time

Cleaner class

From the figure below, you can see that Cleaner inherits the PhantomRefrence virtual reference class, which is essentially a Refrence.

image-20220424103149881

The ReferenceHandler will continuously fetch the reference object from the pending list. The type of the reference object may be of any type. When the reference object is a Cleaner, the clean method of the Cleaner is called directly.

The usage method is also very simple, pass in the object instance and the runnable thread, and when the object is recycled, the run method of the runnable will be triggered

Cleaner.create(this, new Runnable() {
    
    
    @Override
    public void run() {
    
    

    }
});

In most cases, strong references are used in development. In some special business scenarios, other reference types are also used in the development mode. It is recommended that you read this article carefully and use it as appropriate.

Guess you like

Origin blog.csdn.net/qq_21046665/article/details/124094802