Table of Contents
Java Reference source code analysis
Introduction" >Introduction
Strong reference FinalReference
Soft ReferenceSoftReference
Weak ReferenceWeakReference
Virtual referencePhantomReference
ReferenceQueue
Source code analysis
Reference and ReferenceQueue
Internal class ReferenceHandler
ReferenceQueue attribute
ReferenceQueue.enqueue
ReferenceQueue.remove
Specific execution process
Home Java javaTutorial Detailed explanation of Java Reference source code analysis code

Detailed explanation of Java Reference source code analysis code

Mar 19, 2017 pm 03:37 PM

@(Java)[Reference]

Java Reference source code analysis

ReferenceObject encapsulates references to other objects and can be operated like ordinary objects. Under certain restrictions, interaction with the garbage collector is supported. That is, you can use the Reference object to refer to other objects, but it will still be recycled by the garbage collector in the end. Programs sometimes need to be notified after an object is recycled to inform it of changes in the object's reachability.
Java provides four different types of references. The reference levels from high to low are FinalReference, SoftReference, WeakReference, and PhantomReference. Among them, FinalReference is not available for external use. Each type corresponds to a different level of accessibility.

Introduction

Strong reference FinalReference

Strong reference means that there is a directly reachable reference in the program without passing any reference object , such as Object obj = new Object();, obj is a strong reference.

Soft ReferenceSoftReference

Soft reference, not a strong reference, but can be accessed through a soft reference object. For soft reference objects, the garbage collector will decide to recycle the object pointed to by the soft reference only when there is insufficient memory (before an OOM exception is thrown). Soft references are often used to implement memory-sensitive caches.

SoftReference<Object> softRef = new SoftReference<Object>(new Object());
Copy after login

Weak ReferenceWeakReference

Weak reference, non-strong reference and soft reference, but can be accessed through a weak reference object. A weakly referenced object will be recycled as long as it is discovered by the garbage collector, regardless of whether the memory is sufficient. For actual applications, see WeakHashMap, etc.

WeakReference<Object> weakRef = new WeakReference<Object>(new Object());
Copy after login

Virtual referencePhantomReference

Virtual reference, this reference must be used together with the reference queue (ReferenceQueue), and is generally used to track the recycling actions of the garbage collector, such as when the object is recycled , the finalize method of the object will be called. This action can be achieved using virtual references, which is also safer.

Object obj = new Object();
ReferenceQueue<Object> refQueue = new ReferenceQueue<>();
PhantomReference<Object> phantom = new PhantomReference<Object>(obj, refQueue);
Copy after login

ReferenceQueue

As a member of the reference, this queue can be used in combination with the above three reference types. The function of this queue is: when creating a Reference, register the Queue into the Reference. When the object referenced by the Reference is recycled by the garbage collector, the Reference will be placed in the queue, which is equivalent to a notification mechanism.
Example Demo1:

ReferenceQueue queue = new ReferenceQueue();
WeakReference reference = new WeakReference(new Object(), queue);
System.out.println(reference);
System.gc();
Reference reference1 = queue.remove();
System.out.println(reference1);
Copy after login

Source code analysis

Reference and ReferenceQueue

There are several important attributes inside Reference

// 用于保存对象的引用,GC会根据不同Reference来特别对待
private T referent;
// 如果需要通知机制,则保存的对对应的队列
ReferenceQueue<? super T> queue;
/* 这个用于实现一个单向循环链表,用以将保存需要由ReferenceHandler处理的引用 */
Reference next;
static private class Lock { };
// 锁,用于同步pending队列的进队和出队
private static Lock lock = new Lock();
// 此属性保存一个PENDING的队列,配合上述next一起使用
private static Reference pending = null;
Copy after login

Status Figure

详解Java Reference源码分析代码

Internal class ReferenceHandler

ReferenceHandler is a static internal class of Reference, which is used to add Reference instances in the pending queue to different in the ReferenceQueue (depends on the queue in the Reference). The pending elements are added by the GC.
Note: The pending queue is locked here. Personally, I think it is because the GC thread may execute concurrently with the thread where the ReferenceHandler is located, such as when GC uses CMS concurrent collection.
As shown in the following code

// 此线程在静态块中启动,即一旦使用了Reference,则会启动该线程
private static class ReferenceHandler extends Thread {
    public void run() {
        for (;;) {

            Reference r;
            synchronized (lock) {
                if (pending != null) {
                    r = pending;
                    Reference rn = r.next;
                    // 从pending中取下一个元素,如果后继为空,则next指向自身                    pending = (rn == r) ? null : rn;
                    r.next = r;
                } else {
                    try {
                        // 没有则等待,后续加入元素会调用lock.notify唤醒
                        lock.wait();
                    } catch (InterruptedException x) { }
                    continue;
                }
            }
            // ...
            ReferenceQueue q = r.queue;
            // 如果该Reference注册了对应的Queue,则加入到该Queue中
            if (q != ReferenceQueue.NULL) q.enqueue(r);
        }
    }
}
Copy after login

ReferenceQueue attribute

// 用于标识没有注册Queue
static ReferenceQueue NULL = new Null();
// 用于标识已经处于对应的Queue中
static ReferenceQueue ENQUEUED = new Null();

static private class Lock { };
/* 互斥锁,用于同步ReferenceHandler的enqueue和用户线程操作的remove和poll出队操作 */
private Lock lock = new Lock();
// 队列
private volatile Reference<? extends T> head = null;
// 队列中的元素个数
private long queueLength = 0;
Copy after login

ReferenceQueue.enqueue

This method will only be called through the Reference, which is used to put the Reference into the current In the queue

boolean enqueue(Reference<? extends T> r) {    synchronized (r) {        // 判断是否已经入队了
        if (r.queue == ENQUEUED) return false;        synchronized (lock) {
            r.queue = ENQUEUED;            // 单向循环
            r.next = (head == null) ? r : head;
            head = r;
            queueLength++;            if (r instanceof FinalReference) {
                sun.misc.VM.addFinalRefCount(1);
            }            // 通知当前挂起的线程(调用remove时有可能会挂起)
            lock.notifyAll();            return true;
        }
    }
}
Copy after login

ReferenceQueue.remove

public Reference<? extends T> remove(long timeout)    throws IllegalArgumentException, InterruptedException
{    if (timeout < 0) {        throw new IllegalArgumentException("Negative timeout value");
    }    synchronized (lock) {        // 从队列中取出一个元素
        Reference<? extends T> r = reallyPoll();        // 如果不为空,则直接返回
        if (r != null) return r;        for (;;) {            // 否则等待,由enqueue时notify唤醒
            lock.wait(timeout);
            r = reallyPoll();            if (r != null) return r;            if (timeout != 0) return null;
        }
    }
}
Copy after login

Specific execution process

Using the above example Demo1 as an analysis

// 创建一个引用队列
ReferenceQueue queue = new ReferenceQueue();

// 创建虚引用,此时状态为Active,并且Reference.pending为空,当前Reference.queue = 上面创建的queue,并且next=null
WeakReference reference = new WeakReference(new Object(), queue);
System.out.println(reference);
// 当GC执行后,由于是虚引用,所以回收该object对象,并且置于pending上,此时reference的状态为PENDING
System.gc();

/* ReferenceHandler从pending中取下该元素,并且将该元素放入到queue中,此时Reference状态为ENQUEUED,Reference.queue = ReferenceENQUEUED */

/* 当从queue里面取出该元素,则变为INACTIVE,Reference.queue = Reference.NULL */
Reference reference1 = queue.remove();
System.out.println(reference1);
Copy after login

The above is the detailed content of Detailed explanation of Java Reference source code analysis code. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Is the company's security software causing the application to fail to run? How to troubleshoot and solve it? Is the company's security software causing the application to fail to run? How to troubleshoot and solve it? Apr 19, 2025 pm 04:51 PM

Troubleshooting and solutions to the company's security software that causes some applications to not function properly. Many companies will deploy security software in order to ensure internal network security. ...

How to elegantly obtain entity class variable names to build database query conditions? How to elegantly obtain entity class variable names to build database query conditions? Apr 19, 2025 pm 11:42 PM

When using MyBatis-Plus or other ORM frameworks for database operations, it is often necessary to construct query conditions based on the attribute name of the entity class. If you manually every time...

How to simplify field mapping issues in system docking using MapStruct? How to simplify field mapping issues in system docking using MapStruct? Apr 19, 2025 pm 06:21 PM

Field mapping processing in system docking often encounters a difficult problem when performing system docking: how to effectively map the interface fields of system A...

How does IntelliJ IDEA identify the port number of a Spring Boot project without outputting a log? How does IntelliJ IDEA identify the port number of a Spring Boot project without outputting a log? Apr 19, 2025 pm 11:45 PM

Start Spring using IntelliJIDEAUltimate version...

How to elegantly get entity class variable name building query conditions when using TKMyBatis for database query? How to elegantly get entity class variable name building query conditions when using TKMyBatis for database query? Apr 19, 2025 pm 09:51 PM

When using TKMyBatis for database queries, how to gracefully get entity class variable names to build query conditions is a common problem. This article will pin...

How do I convert names to numbers to implement sorting and maintain consistency in groups? How do I convert names to numbers to implement sorting and maintain consistency in groups? Apr 19, 2025 pm 11:30 PM

Solutions to convert names to numbers to implement sorting In many application scenarios, users may need to sort in groups, especially in one...

How to safely convert Java objects to arrays? How to safely convert Java objects to arrays? Apr 19, 2025 pm 11:33 PM

Conversion of Java Objects and Arrays: In-depth discussion of the risks and correct methods of cast type conversion Many Java beginners will encounter the conversion of an object into an array...

E-commerce platform SKU and SPU database design: How to take into account both user-defined attributes and attributeless products? E-commerce platform SKU and SPU database design: How to take into account both user-defined attributes and attributeless products? Apr 19, 2025 pm 11:27 PM

Detailed explanation of the design of SKU and SPU tables on e-commerce platforms This article will discuss the database design issues of SKU and SPU in e-commerce platforms, especially how to deal with user-defined sales...

See all articles