- Java Reference source code analysis
- Introduction
- Strong citation FinalReference
- Soft reference SoftReference
- Weak reference WeakReference
- Phantom reference PhantomReference
- ReferenceQueue
- Source code analysis
- Reference with ReferenceQueue
- State diagram
- Inner class ReferenceHandler
- ReferenceQueue properties
- ReferenceQueue.enqueue
- ReferenceQueue.remove
- Specific execution process
- Application-WeakHashMap
- Entry
- Saved searches
- Use saved searches to filter your results more quickly
- gnodivad/java-the-complete-reference
- Name already in use
- Sign In Required
- Launching GitHub Desktop
- Launching GitHub Desktop
- Launching Xcode
- Launching Visual Studio Code
- Latest commit
- Git stats
- Files
- README.md
- About
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.
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