Interviews often asked about Java reference type principle? Ali P8 architects take you in-depth analysis!

Java in a total of four kinds of reference types (in fact, there are some other reference types such as FinalReference): strong references, soft references, weak references, phantom references.

Wherein the strong reference that we often use Object a = new Object (); this form, and not in the Java class corresponding Reference.

This article is to analyze the soft, weak, quote, implement virtual reference, three reference types are inherited from the Reference class, the main logic also Reference.

problem

Before analysis, before throwing a few questions?

1. Most of the online article to introduce soft reference is: will be recycled in the memory of the time, that insufficient memory is how defined? What is meant by insufficient memory?

2. Most of the online article to introduce phantom reference is: useless, dangling reference and does not determine the object's life cycle. Primarily used to track objects recovered garbage collector activity. Is it really?

3. Phantom reference under which it has used the scene in Jdk in?

Reference

We look at Reference.java in several fields

public abstract class Reference<T> {
   //引用的对象
   private T referent;        
   //回收队列,由使用者在Reference的构造函数中指定
   volatile ReferenceQueue<? super T> queue;
    //当该引用被加入到queue中的时候,该字段被设置为queue中的下一个元素,以形成链表结构
   volatile Reference next;
   //在GC时,JVM底层会维护一个叫DiscoveredList的链表,存放的是Reference对象,discovered字段指向的就是链表中的下一个元素,由JVM设置
   transient private Reference<T> discovered;  
   //进行线程同步的锁对象
   static private class Lock { }
   private static Lock lock = new Lock();
   //等待加入queue的Reference对象,在GC时由JVM设置,会有一个java层的线程(ReferenceHandler)源源不断的从pending中提取元素加入到queue
   private static Reference<Object> pending = null;

Reference object of a life cycle as follows:

Interviews often asked about Java reference type principle?  Ali P8 architects take you in-depth analysis!


It divided into two parts Java Native layers and layers.

Native the GC layer will need to be added to the recovered DiscoveredList in Reference object (the code referenceProcessor.cpp process_discovered_references method), and then move the element DiscoveredList to PendingList (code referenceProcessor.cpp the enqueue_discovered_ref_helper method), the team PendingList Reference is first class in the pending objects.

Look at the code layer of Java

Interviews often asked about Java reference type principle?  Ali P8 architects take you in-depth analysis!


The process is relatively simple: that is extracted from a steady stream of PendingList out element, and then add it to go ReferenceQueue, developers can perceive from the poll ReferenceQueue element to the object to be recovered events.

Also note that for Cleaner type (inherited from phantom reference) object will have additional processing: when it points to an object is recovered, it will call the clean method, which is mainly used for recycling corresponding, in external memory in the heap is recovered outside DirectByteBuffer heap memory with Cleaner, which is a typical application in java virtual reference.

After reading the realization of Reference, and then look at a few achieve class, each of which has different.

SoftReference

Interviews often asked about Java reference type principle?  Ali P8 architects take you in-depth analysis!


Achieve a soft reference is very simple, the more the two fields: clock and timestamp. clock is a static variable, the field will be set to the current time each time the GC. timestamp field will get at each method call assigned to it with clock (if not equal to the target has not been recovered).

What is the role that these two fields is it? It was only recovered at the soft references and insufficient memory when, what does it matter?

The JVM will have to see the source code for the job, because the object needs to be decided whether the recovery is implemented in the GC.

Interviews often asked about Java reference type principle?  Ali P8 architects take you in-depth analysis!


Interviews often asked about Java reference type principle?  Ali P8 architects take you in-depth analysis!


refs_lists stored in a certain reference types found in this GC (phantom reference, soft, weak, references, etc.), acting process_discovered_reflist method is to remove the objects need not be recovered from the off refs_lists, refs_lists last remaining element all the elements need to be recovered, and places the first element is assigned to the above-mentioned Reference.java # pending field.

ReferencePolicy achieve a total of four kinds: NeverClearPolicy, AlwaysClearPolicy, LRUCurrentHeapPolicy, LRUMaxHeapPolicy.

NeverClearPolicy which always returns false, representatives never recovered SoftReference, is not used in the JVM class, AlwaysClearPolicy will never return true, in referenceProcessor.hpp # setup process can be set policy for the AlwaysClearPolicy, as to when it will be used AlwaysClearPolicy, we are interested can study on their own.

LRUCurrentHeapPolicy和LRUMaxHeapPolicy的should_clear_reference方法则是完全相同:

Interviews often asked about Java reference type principle?  Ali P8 architects take you in-depth analysis!


timestamp_clock就是SoftReference的静态字段clock,java_lang_ref_SoftReference::timestamp(p)对应是字段timestamp。如果上次GC后有调用SoftReference#get,interval值为0,否则为若干次GC之间的时间差。

_max_interval则代表了一个临界值,它的值在LRUCurrentHeapPolicy和LRUMaxHeapPolicy两种策略中有差异

Interviews often asked about Java reference type principle?  Ali P8 architects take you in-depth analysis!


其中SoftRefLRUPolicyMSPerMB默认为1000,前者的计算方法和上次GC后可用堆大小有关,后者计算方法和(堆大小-上次gc时堆使用大小)有关。

看到这里你就知道SoftReference到底什么时候被被回收了,它和使用的策略(默认应该是LRUCurrentHeapPolicy),堆可用大小,该SoftReference上一次调用get方法的时间都有关系。

WeakReference

Interviews often asked about Java reference type principle?  Ali P8 architects take you in-depth analysis!


可以看到WeakReference在Java层只是继承了Reference,没有做任何的改动。那referent字段是什么时候被置为null的呢?要搞清楚这个问题我们再看下上文提到过的process_discovered_reflist方法:

Interviews often asked about Java reference type principle?  Ali P8 architects take you in-depth analysis!


Interviews often asked about Java reference type principle?  Ali P8 architects take you in-depth analysis!


Interviews often asked about Java reference type principle?  Ali P8 architects take you in-depth analysis!


不管是弱引用还是其他引用类型,将字段referent置null的操作都发生在process_phase3中,而具体行为是由clear_referent的值决定的。而clear_referent的值则和引用类型相关。

Interviews often asked about Java reference type principle?  Ali P8 architects take you in-depth analysis!


可以看到,对于Soft references和Weak references clear_referent字段传入的都是true,这也符合我们的预期:对象不可达后,引用字段就会被置为null,然后对象就会被回收(对于软引用来说,如果内存足够的话,在Phase 1,相关的引用就会从refs_list中被移除,到Phase 3时refs_list为空集合)。

但对于Final references和 Phantom references,clear_referent字段传入的是false,也就意味着被这两种引用类型引用的对象,如果没有其他额外处理,只要Reference对象还存活,那引用的对象是不会被回收的。Final references和对象是否重写了finalize方法有关,不在本文分析范围之内,我们接下来看看Phantom references。

PhantomReference

Interviews often asked about Java reference type principle?  Ali P8 architects take you in-depth analysis!


可以看到虚引用的get方法永远返回null,我们看个demo。

Interviews often asked about Java reference type principle?  Ali P8 architects take you in-depth analysis!


从以上代码中可以看到,虚引用能够在指向对象不可达时得到一个'通知'(其实所有继承References的类都有这个功能),需要注意的是GC完成后,phanRef.referent依然指向之前创建Object,也就是说Object对象一直没被回收!

而造成这一现象的原因在上一小节末尾已经说了:对于Final references和 Phantom references,clear_referent字段传入的时false,也就意味着被这两种引用类型引用的对象,如果没有其他额外处理,在GC中是不会被回收的。

对于虚引用来说,从refQueue.remove();得到引用对象后,可以调用clear方法强行解除引用和对象之间的关系,使得对象下次可以GC时可以被回收掉。

End

针对文章开头提出的几个问题,看完分析,我们已经能给出回答:

1. We often see online soft reference presentation is: will the recovery in the memory of the time, that insufficient memory is how defined? Why it is called out of memory?

Soft references are recovered low memory, low memory and the definition of the reference object and the current time to get the available heap memory size has a relationship, the calculation formula also been given above.

2. For the online presentation of virtual reference are: non-existent, and several other references are different, the life cycle of virtual reference and does not determine object. Primarily used to track objects recovered garbage collector activity. Is it really?

Strictly speaking, phantom reference will affect the life cycle of the object, if no treatment, as long as the phantom reference is not recovered, and that it references an object will never be recovered. So, in general, after obtaining PhantomReference object from ReferenceQueue, if PhantomReference object is not recovered, then (such as being referenced by other GC ROOT reachable objects), you need to call clear way to lift PhantomReference and its reference to an object reference relationship.

3. Phantom reference under which it has used the scene in Jdk in?

DirectByteBuffer is a phantom reference subclass Cleaner.java to implement external heap memory recovery, follow-up will write an article for the said memory heap outside the ins and outs.

Article feel good old iron to the point of a little brother attention to it!


Guess you like

Origin blog.51cto.com/14480698/2479280