Before you knowWeak Reference , give a simple code :
public class Weakreferencetest {
public static void Main (string[] args) throws Exception {
Object o = new Object ();
The default constructor, which uses Referencequeue.null as the queue
Weakreference<object> WR = new weakreference<object> (o);
System.out.println (wr.get () = = null);
o = null;
System.GC ();
System.out.println (wr.get () = = null);
}
}
output result : False,true
Like to explore the children's shoes will ask , why System. GC after WeakReference will be recycled , How to do it ? Let's go deep into the Reference of the source of the search for a really . There are two internal points to note :
1)pending and discovered members:
See :p ending object First
/* List of References waiting to be enqueued. The collector adds
* References to this list, while the Reference-handler thread removes
* them. This list was protected by the above lock object.
*/
private static Reference pending = NULL;
This object, defined as private, does not have any value assigned to it globally, and according to its comments above, we understand that this variable is dealing with the garbage collection period.
Look at discovered again, the same private, the context does not have anywhere to use it
transient private reference<t> discovered; /* Used by VM */
See its annotations are also explicitly written to the VM.
The above two variables corresponding to the call in the VM, you can refer to OpenJDK in the hotspot source code, in the Hotspot/src/share/vm/memory/referenceprocessor.cpp referenceprocessor: :d the Iscover_reference method. (based on the comments of this method, there are referencebaseddiscovery and refeferentbaseddiscovery two strategies for understanding the virtual machine's handling of reference)
2)Referencehandler thread
This thread is started in the static construction block of the reference class and is set to high priority and daemon state.
What this thread is going to do is keep checking if pending is null, and if pending is not NULL, pending is Enqueue, otherwise the thread enters the wait state.
Through these 2 points, we look at the whole process:
The pending is assigned by the JVM, and the JVM places the Reference object in the pending list when the reference internal Referent object changes.
Combine the o = null in the code EG1; This sentence, it makes the O object satisfies the garbage collection condition, and in the back explicitly calls the System.GC (), the garbage collection carries on the time will mark weakreference the object that referent O is unreachable (makes Wr.get () ==null), and through Assigns a value to pending, triggering the Referencehandler thread processing pending.
The Referencehandler thread is going to enqueue the pending object, but by default we provide the queue, which is the null passed in from the constructor, The fact is that the referencequeue.null,handler thread is used to determine that the queue is referencequeue.null without action, only non-referencequeue.null Queue will enqueue the reference.
Referencequeue.null is equivalent to providing an empty queue to listen to feedback from the garbage collector ( What feedback ?). It means that this quene is for us , for example, in the way Weakhashmap is used, and does not deal with this feedback. ( But the garbage is still recycled ??? isn't It poll time to do things ?)
To process feedback, you must provide a non-referencequeue.null queue. This quene can be seen as a bridge between GC and application, informing the application of the need to process those reference.
When a weakreference begins to return null, the object it points to is ready to be reclaimed, and some cleanup work can be done properly. A referencequeue is passed to a Reference constructor, and when the object is recycled, the virtual opportunity automatically inserts the object into the Referencequeue, and Weakhashmap uses Referencequeue to clear the key There are no strong references to entries.
In Weakhashmap, a non-null referencequeue is provided internally.
Private final referencequeue<k> queue = new referencequeue<k> ();
This queue is used as the listener when an element is added to the Weakhashmap.
See the following sentence in the Put method:
Tab[i] = new Entry<k,v> (K, value, queue, H, e);
Here entry is an inner class that inherits the WeakReference
Class Entry<k,v> extends weakreference<k> implements Map.entry<k,v>
Weakhashmap put, size, clear will be called indirectly or directly to the Expungestaleentries () method.
WeakReference &&reference Quene &&GC