java中的4種引用和GC Roots

https://juejin.im/post/5d06de9d51882559ee6f4212?utm_source=gold_browser_extensionjava

1.首先,四種引用以下:算法

  • FinalReference 強引用
  • SoftReference 軟引用
  • WeakReference 弱引用
  • PhantomReference 虛引用

2.四種引用的特色:數據庫

強引用:被new出來的對象都是的引用都是強引用安全

              eg:Student s = new Student();post

               回收時機:不會被回收,會發生內存溢出。this

 

 

軟引用:軟引用關聯的對象,在內存不夠的狀況下,會把這些軟引用關聯的對象列入垃圾回收範圍中,而後進行回收,也就是說軟引用並不是是徹底安全的,在內存不夠的狀況下是會被垃圾回收器回收掉的。spa

    public static void main(String[] args) {
        SoftReference[] references = new SoftReference[5];
        ReferenceQueue<ReferenceTestObject> referenceTestObjectReferenceQueue = new ReferenceQueue<>();
        for(int i =0 ;i<5;i++){
            references[i] = new SoftReference(new ReferenceTestObject("ahahh-"+i),referenceTestObjectReferenceQueue);
        }

        for(int i =0 ;i<5;i++){
            Object o = references[i].get();
            if(o == null){
                System.out.println("null");
            }else{
                System.out.println(((ReferenceTestObject)o).name);
            }
        }
    }

  

使用場景:使用軟引用來保存從數據庫中取出的數據,具體是作了一箇中間層的封裝,該中間層的做用就是在get出數據的時候會去判斷數據是否爲null,若是是爲null再次從數據庫讀取,讀取後再放入軟引用的集合中,這樣的作法是能夠避免內存溢出code

 

弱引用:只要發生GC都會被回收掉對象

eg:ThreadLocalMap的keyblog

    static class ThreadLocalMap {

        /**
         * The entries in this hash map extend WeakReference, using
         * its main ref field as the key (which is always a
         * ThreadLocal object).  Note that null keys (i.e. entry.get()
         * == null) mean that the key is no longer referenced, so the
         * entry can be expunged from table.  Such entries are referred to
         * as "stale entries" in the code that follows.
         */
        static class Entry extends WeakReference<ThreadLocal<?>> {
            /** The value associated with this ThreadLocal. */
            Object value;

            Entry(ThreadLocal<?> k, Object v) {
                super(k);
                value = v;
            }
        }
    ......}

 

虛引用
有和沒有一個樣:沒法經過虛引用來獲取對象的實例,可是仍是有做用的。、
做用就是能在這個對象被收集器回收時收到一個系統通知,實現追蹤垃圾收集器的回收動做,好比在對象被回收的時候,會調用該對象的finalize方法。

 

ReferenceQueue 引用隊列

在建立Reference時,手動將Queue註冊到Reference中,而當該Reference所引用的對象被垃圾收集器回收時,JVM會將該Reference放到該隊列中,而咱們即可以對該隊列作些其餘業務,至關於一種通知機制。

 

可達性分析:

JVM怎麼知道引用在不在,這就涉及到了JVM的可達性分析算法了 JVM的可達性分析算法的簡單思路就是經過一系列GC Roots做爲出發點,向下搜索,搜索所走過的路徑稱爲引用鏈,當一個對象到GC Roots沒有任何引用鏈,即代表從GC Roots到這個對象不可達時,證實此對象不可用,可被回收。以下圖所示

 

 

對象四、五、6都是可被回收的。 那麼問題來了,哪些對象能夠做爲GC Roots呢? 這裏給出幾個,以下

  • 虛擬機棧中引用的對象

  • 方法區中類靜態屬性引用的對象

  • 方法區中常量引用的對象

  • 本地方法棧JNI引用的對象

相關文章
相關標籤/搜索