java中的4種引用和GC Roots


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

1.首先,四種引用如下:

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

2.四種引用的特點:

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

              eg:Student s = new Student();

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

 

 

軟引用:軟引用關聯的對象,在內存不夠的情況下,會把這些軟引用關聯的對象列入垃圾回收范圍中,然后進行回收,也就是說軟引用並非是完全安全的,在內存不夠的情況下是會被垃圾回收器回收掉的。

    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再次從數據庫讀取,讀取后再放入軟引用的集合中,這樣的做法是可以避免內存溢出

 

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

eg:ThreadLocalMap的key

    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到這個對象不可達時,證明此對象不可用,可被回收。如下圖所示

 

 

對象4、5、6都是可被回收的。 那么問題來了,哪些對象可以作為GC Roots呢? 這里給出幾個,如下

  • 虛擬機棧中引用的對象

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

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

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM