麻豆黑色丝袜jk制服福利网站-麻豆精品传媒视频观看-麻豆精品传媒一二三区在线视频-麻豆精选传媒4区2021-在线视频99-在线视频a

千鋒教育-做有情懷、有良心、有品質的職業教育機構

手機站
千鋒教育

千鋒學習站 | 隨時隨地免費學

千鋒教育

掃一掃進入千鋒手機站

領取全套視頻
千鋒教育

關注千鋒學習站小程序
隨時隨地免費學習課程

當前位置:首頁  >  技術干貨  > 強引用和軟引用和弱引用以及虛引用?

強引用和軟引用和弱引用以及虛引用?

來源:千鋒教育
發布人:qyf
時間: 2022-06-07 17:08:00 1654592880

  ava執行GC判斷對象是否存活有兩種方式其中一種是引用計數。

  引用計數:Java堆中每一個對象都有一個引用計數屬性,引用每新增1次計數加1,引用每釋放1次計數減1。

  在JDK 1.2以前的版本中,若一個對象不被任何變量引用,那么程序就無法再使用這個對象。也就是說,只有對象處于(reachable)可達狀態,程序才能使用它。

  從JDK 1.2版本開始,對象的引用被劃分為4種級別,從而使程序能更加靈活地控制對象的生命周期。這4種級別由高到低依次為:強引用、軟引用、弱引用和虛引用。

圖片1

  1. 強引用(StrongReference)

  強引用是使用最普遍的引用。如果一個對象具有強引用,那垃圾回收器絕不會回收它。

  當內存空間不足時,Java虛擬機寧愿拋出OutOfMemoryError錯誤,使程序異常終止,也不會靠隨意回收具有強引用的對象來解決內存不足的問題。 如果強引用對象不使用時,需要弱化從而使GC能夠回收,如下:

  strongReference = null;

  顯式地設置strongReference對象為null,或讓其超出對象的生命周期范圍,則gc認為該對象不存在引用,這時就可以回收這個對象。具體什么時候收集這要取決于GC算法。

    public void test() {

        Object strongReference = new Object();

    }

  在這個方法的內部有一個強引用,這個引用保存在Java棧中,而真正的引用內容(Object)保存在Java堆中。 當這個方法運行完成后,就會退出方法棧,則引用對象的引用數為0,這個對象會被回收。

  但是如果這個strongReference是全局變量時,就需要在不用這個對象時賦值為null,因為強引用不會被垃圾回收。

  2. 軟引用(SoftReference)

  如果一個對象只具有軟引用,則內存空間充足時,垃圾回收器就不會回收它;如果內存空間不足了,就會回收這些對象的內存。只要垃圾回收器沒有回收它,該對象就可以被程序使用。

  軟引用可用來實現內存敏感的高速緩存。

    // 強引用

    String strongReference = new String("abc");

    // 軟引用

    String str = new String("abc");

    SoftReference<String> softReference = new SoftReference<String>(str);

  軟引用可以和一個引用隊列(ReferenceQueue)聯合使用。如果軟引用所引用對象被垃圾回收,JAVA虛擬機就會把這個軟引用加入到與之關聯的引用隊列中。

    ReferenceQueue<String> referenceQueue = new ReferenceQueue<>();

    String str = new String("abc");

    SoftReference<String> softReference = new SoftReference<>(str, referenceQueue);

    str = null;

    // Notify GC

    System.gc();

    System.out.println(softReference.get()); // abc

    Reference<? extends String> reference = referenceQueue.poll();

    System.out.println(reference); //null

  注意:軟引用對象是在jvm內存不夠的時候才會被回收,我們調用System.gc()方法只是起通知作用,JVM什么時候掃描回收對象是JVM自己的狀態決定的。就算掃描到軟引用對象也不一定會回收它,只有內存不夠的時候才會回收。當內存不足時,JVM首先將軟引用中的對象引用置為null,然后通知垃圾回收器進行回收:

    if(JVM內存不足) {

        // 將軟引用中的對象引用置為null

        str = null;

        // 通知垃圾回收器進行回收

        System.gc();

    }

  也就是說,垃圾收集線程會在虛擬機拋出OutOfMemoryError之前回收軟引用對象,而且虛擬機會盡可能優先回收長時間閑置不用的軟引用對象。對那些剛構建的或剛使用過的**"較新的"軟對象會被虛擬機盡可能保留**,這就是引入引用隊列ReferenceQueue的原因。

  應用場景:

  瀏覽器的后退按鈕。按后退時,這個后退時顯示的網頁內容是重新進行請求還是從緩存中取出呢?這就要看具體的實現策略了。

  1. 如果一個網頁在瀏覽結束時就進行內容的回收,則按后退查看前面瀏覽過的頁面時,需要重新構建;

  2. 如果將瀏覽過的網頁存儲到內存中會造成內存的大量浪費,甚至會造成內存溢出。

  這時候就可以使用軟引用,很好的解決了實際的問題:

    // 獲取瀏覽器對象進行瀏覽

    Browser browser = new Browser();

    // 從后臺程序加載瀏覽頁面

    BrowserPage page = browser.getPage();

    // 將瀏覽完畢的頁面置為軟引用

    SoftReference softReference = new SoftReference(page);

    // 回退或者再次瀏覽此頁面時

    if(softReference.get() != null) {

        // 內存充足,還沒有被回收器回收,直接獲取緩存

        page = softReference.get();

    } else {

        // 內存不足,軟引用的對象已經回收

        page = browser.getPage();

        // 重新構建軟引用

        softReference = new SoftReference(page);

    }

  3. 弱引用(WeakReference)

  弱引用與軟引用的區別在于:只具有弱引用的對象擁有更短暫的生命周期。在垃圾回收器線程掃描它所管轄的內存區域的過程中,一旦發現了只具有弱引用的對象,不管當前內存空間足夠與否,都會回收它的內存。不過,由于垃圾回收器是一個優先級很低的線程,因此不一定會很快發現那些只具有弱引用的對象。

    String str = new String("abc");

    WeakReference<String> weakReference = new WeakReference<>(str);

    str = null;復制代碼

  JVM首先將軟引用中的對象引用置為null,然后通知垃圾回收器進行回收:

    str = null;

    System.gc();

  注意:如果一個對象是偶爾(很少)的使用,并且希望在使用時隨時就能獲取到,但又不想影響此對象的垃圾收集,那么你應該用Weak Reference來記住此對象。

  下面的代碼會讓一個弱引用再次變為一個強引用:

    String str = new String("abc");

    WeakReference<String> weakReference = new WeakReference<>(str);

    // 弱引用轉強引用

    String strongReference = weakReference.get();

  同樣,弱引用可以和一個引用隊列(ReferenceQueue)聯合使用,如果弱引用所引用的對象被垃圾回收,Java虛擬機就會把這個弱引用加入到與之關聯的引用隊列中。

  簡單測試:

GCTarget.java

public class GCTarget {

    // 對象的ID

    public String id;

    // 占用內存空間

    byte[] buffer = new byte[1024];

    public GCTarget(String id) {

        this.id = id;

    }

    protected void finalize() throws Throwable {

        // 執行垃圾回收時打印顯示對象ID

        System.out.println("Finalizing GCTarget, id is : " + id);

    }

}

GCTargetWeakReference.java

public class GCTargetWeakReference extends WeakReference<GCTarget> {

    // 弱引用的ID

    public String id;

    public GCTargetWeakReference(GCTarget gcTarget,

              ReferenceQueue<? super GCTarget> queue) {

        super(gcTarget, queue);

        this.id = gcTarget.id;

    }

    protected void finalize() {

        System.out.println("Finalizing GCTargetWeakReference " + id);

    }

}

WeakReferenceTest.java

public class WeakReferenceTest {

    // 弱引用隊列

    private final static ReferenceQueue<GCTarget> REFERENCE_QUEUE = new ReferenceQueue<>();

    public static void main(String[] args) {

        LinkedList<GCTargetWeakReference> gcTargetList = new LinkedList<>();

        // 創建弱引用的對象,依次加入鏈表中

        for (int i = 0; i < 5; i++) {

            GCTarget gcTarget = new GCTarget(String.valueOf(i));

            GCTargetWeakReference weakReference = new GCTargetWeakReference(gcTarget,

                REFERENCE_QUEUE);

            gcTargetList.add(weakReference);

 

            System.out.println("Just created GCTargetWeakReference obj: " +

                gcTargetList.getLast());

        }

        // 通知GC進行垃圾回收

        System.gc();

        try {

            // 休息幾分鐘,等待上面的垃圾回收線程運行完成

            Thread.sleep(6000);

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

        // 檢查關聯的引用隊列是否為空

        Reference<? extends GCTarget> reference;

        while((reference = REFERENCE_QUEUE.poll()) != null) {

            if(reference instanceof GCTargetWeakReference) {

                System.out.println("In queue, id is: " +

                    ((GCTargetWeakReference) (reference)).id);

            }

        }

    }

}

  可見WeakReference對象的生命周期基本由垃圾回收器決定,一旦垃圾回收線程發現了弱引用對象,在下一次GC過程中就會對其進行回收。

  4. 虛引用(PhantomReference)

  虛引用顧名思義,就是形同虛設。與其他幾種引用都不同,虛引用并不會決定對象的生命周期。如果一個對象僅持有虛引用,那么它就和沒有任何引用一樣,在任何時候都可能被垃圾回收器回收。

  應用場景:

  虛引用主要用來跟蹤對象被垃圾回收器回收的活動。 虛引用與軟引用和弱引用的一個區別在于:

  虛引用必須和引用隊列(ReferenceQueue)聯合使用。當垃圾回收器準備回收一個對象時,如果發現它還有虛引用,就會在回收對象的內存之前,把這個虛引用加入到與之關聯的引用隊列中。

    String str = new String("abc");

    ReferenceQueue queue = new ReferenceQueue();

    // 創建虛引用,要求必須與一個引用隊列關聯

    PhantomReference pr = new PhantomReference(str, queue);復制代碼

  程序可以通過判斷引用隊列中是否已經加入了虛引用,來了解被引用的對象是否將要進行垃圾回收。如果程序發現某個虛引用已經被加入到引用隊列,那么就可以在所引用的對象的內存被回收之前采取必要的行動。

  總結

  Java中4種引用的級別和強度由高到低依次為:強引用 -> 軟引用 -> 弱引用 -> 虛引用

  當垃圾回收器回收時,某些對象會被回收,某些不會被回收。垃圾回收器會從根對象Object來標記存活的對象,然后將某些不可達的對象和一些引用的對象進行回收。

  通過表格來說明一下,如下:

引用類型

被垃圾回收時間

用途

生存時間

強引用

從來不會

對象的一般狀態

JVM停止運行時終止

軟引用

當內存不足時

對象緩存

內存不足時終止

弱引用

正常垃圾回收時

對象緩存

垃圾回收后終止

虛引用

正常垃圾回收時

跟蹤對象的垃圾回收

垃圾回收后終止

  更多關于“Java培訓”的問題,歡迎咨詢千鋒教育在線名師。千鋒已有十余年的培訓經驗,課程大綱更科學更專業,有針對零基礎的就業班,有針對想提升技術的好程序員班,高品質課程助理你實現java程序員夢想。

tags:
聲明:本站稿件版權均屬千鋒教育所有,未經許可不得擅自轉載。
10年以上業內強師集結,手把手帶你蛻變精英
請您保持通訊暢通,專屬學習老師24小時內將與您1V1溝通
免費領取
今日已有369人領取成功
劉同學 138****2860 剛剛成功領取
王同學 131****2015 剛剛成功領取
張同學 133****4652 剛剛成功領取
李同學 135****8607 剛剛成功領取
楊同學 132****5667 剛剛成功領取
岳同學 134****6652 剛剛成功領取
梁同學 157****2950 剛剛成功領取
劉同學 189****1015 剛剛成功領取
張同學 155****4678 剛剛成功領取
鄒同學 139****2907 剛剛成功領取
董同學 138****2867 剛剛成功領取
周同學 136****3602 剛剛成功領取
相關推薦HOT
主站蜘蛛池模板: 男人的好在线观看免费视频| 两人夜晚打扑克剧烈运动| 视频在线免费观看资源| 一个人看的www免费高清中文字幕| 国产精品福利一区二区| 日本漫画囗工番库本全彩| 天天做天天爱天天爽综合网| 国产人成免费视频| 天堂在线中文字幕| 欧美日韩一级二级三级| a毛片在线看片免费| 三级伦理在线| 欧美69影院| 国产乱子伦| 麻豆精品不卡国产免费看 | 欧美va在线观看| 美女毛片在线观看| 久久午夜神器| 久操电影| 第四色最新网站| 精品国产www| 美女范冰冰hdxxxx| 色哟哟视频在线| a级毛片免费观看在线播放| 国产性生交xxxxx免费| maya玛雅□一亚洲电影| 噜噜嘿在线视频免费观看| 美女的尿口免费看软件| 忘忧草日本在线播放www| 波多野给衣一区二区三区| 国产凌凌漆国语| 护士在办公室里被躁视频| 日本三人交xxx69| 2017狠狠干| 国产精品嫩草影院一二三区入口 | 毛茸茸女人| 黄色一级片日本| 成年女人免费播放影院| 久久香蕉综合色一综合色88| 又爽又黄又无遮挡网站| 腿张大点我就可以吃扇贝了|