Java reference source code

Java Reference source code analysis

Reference Objects encapsulate references to other objects, can operate like ordinary objects, and support interaction with the garbage collector under certain restrictions. That is, you can use the Reference object to refer to other objects, but they will eventually be recycled by the garbage collector. The program sometimes needs to be notified after the object is reclaimed to inform that the reachability of the object has changed.
Java provides four different types of references, the reference level from high to low is FinalReference , SoftReference , WeakReference , PhantomReference . among them FinalReference Not for external use. Each type corresponds to a different level of accessibility.

Introduction

Strong citation FinalReference

A strong reference means that there is a directly reachable reference in the program without any reference object. For example, in Object obj = new Object();, obj is a strong reference.

Soft reference SoftReference

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

SoftReference softRef = new SoftReference(new Object()); 

Weak reference WeakReference

Weak references, non-strong references and soft references, but can be accessed through weak reference objects. Weakly referenced objects, regardless of whether the memory is sufficient, as long as they are found by the garbage collector, the referenced objects will be recycled. See the actual application WeakHashMap Wait.

WeakReference weakRef = new WeakReference(new Object()); 

Phantom reference PhantomReference

Dummy reference, the reference must be in the reference queue ( ReferenceQueue ) Is used together, and is generally used to implement the recycling action of the tracking garbage collector. For example, when the object is recycled, the finalize method of the object will be called. This action can be achieved by using a virtual reference, which is also safer.

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

ReferenceQueue

As a member of the reference, the queue can be used in combination with the above three reference types. The role of the queue is: when the Reference is created, the Queue is registered in the Reference, and when the object referenced by the Reference is recycled by the garbage collector, Put the Reference 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); 

Source code analysis

Reference with ReferenceQueue

Reference There are several important attributes inside

// Used to save the reference of the object, GC will treat it according to different References private T referent; // If a notification mechanism is needed, the corresponding queue of the saved pair ReferenceQueue queue; /* This is used to implement a one-way circular linked list to save references that need to be processed by ReferenceHandler */ Reference next; static private class Lock < >; // Lock, used to synchronize the incoming and outgoing queue of the pending queue private static Lock lock = new Lock(); // This attribute saves a PENDING queue, used in conjunction with the above next private static Reference pending = null; 

State diagram

Inner class ReferenceHandler

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

// This thread is started in a static block, that is, once the Reference is used, the thread will be started private static class ReferenceHandler extends Thread < public void run() < for (;;) < Reference r; synchronized (lock) < if (pending != null) < r = pending; Reference rn = r.next; // Take the next element from pending, if the successor is empty, then next points to itself pending = (rn == r)? Null: rn; r.next = r; >else < try < // If you don’t have one, wait, the subsequent addition of elements will call lock.notify to wake up lock.wait(); >catch (InterruptedException x) < >continue; > > // . ReferenceQueue q = r.queue; // If the Reference has registered the corresponding Queue, add it to the Queue if (q != ReferenceQueue.NULL) q.enqueue(r); > > > 

ReferenceQueue properties

// Used to identify that the Queue is not registered static ReferenceQueue NULL = new Null(); // Used to identify that it is already in the corresponding Queue static ReferenceQueue ENQUEUED = new Null(); static private class Lock < >; /* Mutex, used to synchronize the enqueue of ReferenceHandler and remove and poll dequeue operations of user thread operations */ private Lock lock = new Lock(); // queue private volatile Reference head = null; // The number of elements in the queue private long queueLength = 0; 

ReferenceQueue.enqueue

This method will only be called through the Reference to put the Reference into the current queue

boolean enqueue(Reference r) < synchronized (r) < // Determine if you have joined the team if (r.queue == ENQUEUED) return false; synchronized (lock) < r.queue = ENQUEUED; // one-way loop r.next = (head == null) ? r : head; head = r; queueLength++; if (r instanceof FinalReference) < sun.misc.VM.addFinalRefCount(1); >// Notify the currently suspended thread (it may be suspended when calling remove) lock.notifyAll(); return true; > > > 

ReferenceQueue.remove

public Reference remove(long timeout) throws IllegalArgumentException, InterruptedException < if (timeout < 0) < throw new IllegalArgumentException("Negative timeout value"); >synchronized (lock) < // Take an element from the queue Referencer = reallyPoll(); // If it is not empty, return directly if (r != null) return r; for (;;) < // Otherwise, wait, wake up by notify when enqueue lock.wait(timeout); r = reallyPoll(); if (r != null) return r; if (timeout != 0) return null; >> > 

Specific execution process

Take the above example Demo1 as an analysis

// Create a reference queue ReferenceQueue queue = new ReferenceQueue(); // Create a dummy reference, at this time the status is Active, and Reference.pending is empty, the current Reference.queue = the queue created above, and next=null WeakReference reference = new WeakReference(new Object(), queue); System.out.println(reference); // When the GC is executed, because it is a phantom reference, the object is recycled and placed on pending. At this time, the state of the reference is PENDING System.gc(); /* ReferenceHandler removes the element from pending and puts the element into the queue. At this time, the Reference state is ENQUEUED, Reference.queue = ReferenceENQUEUED */ /* When the element is taken out of the queue, it becomes INACTIVE, Reference.queue = Reference.NULL */ Reference reference1 = queue.remove(); System.out.println(reference1); 

Application-WeakHashMap

In use, WeakHashMap and HashMap type are both Hash + linked list to resolve conflicts. The only difference is that the former Key is implemented using virtual references, that is, when garbage collection is performed, it is recycled. At this time, WeakHashMap will be used next time. During operation, remove it from the Map according to the recovered Key.

Entry

When an Entry is created, it will be registered in the queue of the current Map property. When the key is recycled, the Entry will be placed in the queue. Whenever the Map is operated, the original Value will be cleared. (It is carried out by the expungeStaleEntries method, and a separate thread is not started for processing, there is no need, this simplifies the logic and avoids the overhead of locking)

// External WeakHashMap attributes private final ReferenceQueue queue = new ReferenceQueue<>(); /* The integrated WeakReference is used here instead of direct use, because when it is recycled, the specific Key is not known. Here you need to add some additional attributes to WeakReference so that you can locate the specific when notified after being recycled Key/value */ private static class Entry extends WeakReference implements Map.Entry  < // This attribute cannot be added to the key, otherwise it will cause a strong reference and cannot be regarded as a WeakReference to be recycled V value; int hash; Entrynext; Entry(Object key, V value, ReferenceQueue queue, int hash, Entry next) < super(key, queue); this.value = value; this.hash = hash; this.next = next; >// . > 

Источник

Saved searches

Use saved searches to filter your results more quickly

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.

Source code for «Java: The Complete Reference, Eleventh Edition» by Herbert Schildt

gnodivad/java-the-complete-reference

This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Sign In Required

Please sign in to use Codespaces.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching Xcode

If nothing happens, download Xcode and try again.

Launching Visual Studio Code

Your codespace will open once ready.

There was a problem preparing your codespace, please try again.

Latest commit

Git stats

Files

Failed to load latest commit information.

README.md

Java: The Complete Reference, Eleventh Edition

This repo consist code example for the book.

Java: The Complete Reference, Eleventh Edition

Chapter Title Completed
01 The History and Evolution of Java
02 An Overview of Java
03 Data Types, Variables, and Arrays
04 Operators
05 Control Statements
06 Introducing Classes
07 A Close Look at Methods and Classes
08 Inheritance
09 Packages and Interfaces
10 Exception Handling
11 Multithreaded Programming
12 Enumerations, Autoboxing, and Annotations
13 Try-with-Resources, and Other Topics
14 Generics
15 Lambda Expressions
16 Modules
17 String Handling
18 Exploring java.lang
19 java.util Part 1: The Collections Framework
20 java.util Part 2: More Utility Classes
21 Input/Output: Exploring java.io
22 Exploring NIO
23 Networking
24 Event Handling
25 Introducing the AWT: Working with Windows, Graphics, and Text
26 Using AWT Controls, Layout Managers, and Menus
27 Images
28 The Concurrency Utilities
29 The Stream API
30 Regular Expressions and Other Packages
31 Introducing Swing
32 Exploring Swing
33 Introducing Swing Menus
34 Java Beans
35 Introducing Servlets

About

Source code for «Java: The Complete Reference, Eleventh Edition» by Herbert Schildt

Источник

Читайте также:  Coloring icons with css
Оцените статью