1. 程式人生 > >jvm軟引用、強引用、虛引用簡介

jvm軟引用、強引用、虛引用簡介

轉自:http://www.cnblogs.com/dolphin0520/p/3784171.html

想必很多朋友對OOM(OutOfMemory)這個錯誤不會陌生,而當遇到這種錯誤如何有效地解決這個問題呢?今天我們就來說一下如何利用軟引用和弱引用來有效地解決程式中出現的OOM問題。下面是本文的目錄大綱:

  一.瞭解 強引用、軟引用、弱引用、虛引用的概念

  二.進一步理解軟引用和弱引用

  三.如何利用軟引用和弱引用解決OOM問題

  如果有不正之處,希望諒解和批評指正,不勝感激。

  請尊重作者勞動成果,轉載請標明原文連結:

一.瞭解 強引用、軟引用、弱引用、虛引用的概念

  在Java中,雖然不需要程式設計師手動去管理物件的生命週期,但是如果希望某些物件具備一定的生命週期的話(比如記憶體不足時JVM就會自動回收某些物件從而避免OutOfMemory的錯誤)就需要用到軟引用和弱引用了。

  從Java SE2開始,就提供了四種類型的引用:強引用、軟引用、弱引用和虛引用。Java中提供這四種引用型別主要有兩個目的:第一是可以讓程式設計師通過程式碼的方式決定某些物件的生命週期;第二是有利於JVM進行垃圾回收。下面來闡述一下這四種類型引用的概念:

  1.強引用(StrongReference)

  強引用就是指在程式程式碼之中普遍存在的,比如下面這段程式碼中的object和str都是強引用:

12Object object = new Object();String str = "hello";

  只要某個物件有強引用與之關聯,JVM必定不會回收這個物件,即使在記憶體不足的情況下,JVM寧願丟擲OutOfMemory錯誤也不會回收這種物件。比如下面這段程式碼:

12345678910public class Main {public static void main(String[] args) {new Main().fun1();}public void fun1() {Object object = new Object();Object[] objArr = new Object[1000];}}

  當執行至Object[] objArr = new Object[1000];這句時,如果記憶體不足,JVM會丟擲OOM錯誤也不會回收object指向的物件。不過要注意的是,當fun1執行完之後,object和objArr都已經不存在了,所以它們指向的物件都會被JVM回收。

  如果想中斷強引用和某個物件之間的關聯,可以顯示地將引用賦值為null,這樣一來的話,JVM在合適的時間就會回收該物件。

  比如Vector類的clear方法中就是通過將引用賦值為null來實現清理工作的:

複製程式碼
 /**
     * Removes the element at the specified position in this Vector.
     * Shifts any subsequent elements to the left (subtracts one from their
     * indices).  Returns the element that was removed from the Vector.
     *
     * @throws ArrayIndexOutOfBoundsException if the index is out of range
     *         ({@code index < 0 || index >= size()})
     * @param index the index of the element to be removed
     * @return element that was removed
     * @since 1.2
     */
    public synchronized E remove(int index) {
    modCount++;
    if (index >= elementCount)
        throw new ArrayIndexOutOfBoundsException(index);
    Object oldValue = elementData[index];

    int numMoved = elementCount - index - 1;
    if (numMoved > 0)
        System.arraycopy(elementData, index+1, elementData, index,
                 numMoved);
    elementData[--elementCount] = null; // Let gc do its work

    return (E)oldValue;
    }
複製程式碼

  2.軟引用(SoftReference)

  軟引用是用來描述一些有用但並不是必需的物件,在Java中用java.lang.ref.SoftReference類來表示。對於軟引用關聯著的物件,只有在記憶體不足的時候JVM才會回收該物件。因此,這一點可以很好地用來解決OOM的問題,並且這個特性很適合用來實現快取:比如網頁快取、圖片快取等。

  軟引用可以和一個引用佇列(ReferenceQueue)聯合使用,如果軟引用所引用的物件被JVM回收,這個軟引用就會被加入到與之關聯的引用佇列中。下面是一個使用示例:

123456789import java.lang.ref.SoftReference;public class Main {public static void main(String[] args) {SoftReference<String> sr = new SoftReference<String>(new String("hello"));System.out.println(sr.get());}}

  3.弱引用(WeakReference)

  弱引用也是用來描述非必需物件的,當JVM進行垃圾回收時,無論記憶體是否充足,都會回收被弱引用關聯的物件。在java中,用java.lang.ref.WeakReference類來表示。下面是使用示例:

123456789101112import java.lang.ref.WeakReference;public class Main {public static void main(String[] args) {WeakReference<String> sr = new WeakReference<String>(new String("hello"));System.out.println(sr.get());System.gc();                //通知JVM的gc進行垃圾回收System.out.println(sr.get());}}

  輸出結果為:

hello
null

  第二個輸出結果是null,這說明只要JVM進行垃圾回收,被弱引用關聯的物件必定會被回收掉。不過要注意的是,這裡所說的被弱引用關聯的物件是指只有弱引用與之關聯,如果存在強引用同時與之關聯,則進行垃圾回收時也不會回收該物件(軟引用也是如此)。

  弱引用可以和一個引用佇列(ReferenceQueue)聯合使用,如果弱引用所引用的物件被JVM回收,這個軟引用就會被加入到與之關聯的引用佇列中。

  4.虛引用(PhantomReference)

  虛引用和前面的軟引用、弱引用不同,它並不影響物件的生命週期。在java中用java.lang.ref.PhantomReference類表示。如果一個物件與虛引用關聯,則跟沒有引用與之關聯一樣,在任何時候都可能被垃圾回收器回收。

  要注意的是,虛引用必須和引用佇列關聯使用,當垃圾回收器準備回收一個物件時,如果發現它還有虛引用,就會把這個虛引用加入到與之 關聯的引用佇列中。程式可以通過判斷引用佇列中是否已經加入了虛引用,來了解被引用的物件是否將要被垃圾回收。如果程式發現某個虛引用已經被加入到引用佇列,那麼就可以在所引用的物件的記憶體被回收之前採取必要的行動。

123456

相關推薦

程式語言弱型別型別動態型別靜態型別語言的區別

將知識點分門別類可以更好的記憶,程式語言也是,同類型的語言之間也可以相互印證,更全面的理解。 下面轉自知乎。 基礎概念 Program Errorstrapped errors。直譯器或編譯器不能處理的錯誤。導致程式終止執行,如除0,Java中陣列越界訪問untrapped

關於弱一致性一致性順序一致性

    在分散式資料系統中,也有一個帽子原理(CAP Theorem),不過此帽子非彼帽子。CAP原理中,有三個要素,CAP原理指的是,這三個要素最多隻能同時實現兩點,不可能三者兼顧: 一致性(Consistency) 可用性(Availability) 分

一個實現瀏覽器網頁與本地程式之間進行雙向呼叫的輕量級相容可擴充套件的外掛開發平臺—本網通

       通過本網通外掛平臺可實現在網頁中的JavaScript指令碼無障礙訪問本地電腦的硬體、呼叫本地系統的API及相關元件,同時可徹底解決ActiveX元件在Chrome、FireFox、Opera、Edge、Safari等瀏覽器各版本的相容使用問題。 系統相容性:

弱型別型別動態型別靜態型別語言的區別是什麼?

https://www.zhihu.com/question/19918532 型別系統的一些概念,眾說紛紜,使用上也比較亂。有些東西,甚至不好嚴格定義。以下算學術界的一種相對“嚴格”的說法。 1. 先定義一些基礎概念 Program Errors trapped err

弱型別型別動態型別靜態型別語言的區別

1. 先定義一些基礎概念Program Errors trapped errors。導致程式終止執行,如除0,Java中陣列越界訪問untrapped errors。 出錯後繼續執行,但可能出現任意行為。如C裡的緩衝區溢位、Jump到錯誤地址Forbidden Behaviours 語言設計時,可以定義一組f

jvm引用引用引用簡介

轉自:http://www.cnblogs.com/dolphin0520/p/3784171.html想必很多朋友對OOM(OutOfMemory)這個錯誤不會陌生,而當遇到這種錯誤如何有效地解決這個問題呢?今天我們就來說一下如何利用軟引用和弱引用來有效地解決程式中出現的O

JVM】如何理解引用引用引用引用

整體架構 強引用 強引用是預設支援,當記憶體不足的時候,JVM開始垃圾回收,對於強引用的物件,就算是出現了OOM也不會回收物件。 強引用是最常見的普通物件引用,只要還有強引用指向物件,物件就存活,垃圾回收器不會處理存活物件。一般把一個物件賦給一個引用變數,這個引用變數就是強引用。當一個物件被強引用變數所引用

【案例演示】JVM引用引用引用引用

1.背景 想要理解物件什麼時候回收,就要理解到物件引用這個概念,於是有了下文 2.java中引用物件結構圖 3.引用詳解 3.1.什麼是強引用 a.當記憶體不足,JVM開始垃圾回收,對於強引用的物件,就算是出現了00M也不會對該物件進行回收,死都不收。 b.強引用是我們最常見的普通物件引用,只要還有強引用指

引用引用引用引用

enc 存在 bject 永遠 足夠 列表 設置 系統通知 內存溢出 概念我們希望能描述這樣一類對象:在內存空間還足夠時,則能保留在內存之中;如果內存空間在進行垃圾收集後還是非常緊張,則可以拋棄這些對象。在JDK 1.2之後,Java對引用的概念進行了擴充,將引用分為強引用

java 談談引用引用(Strong Reference)引用(Soft Reference)引用(Weak Reference)引用(Phantom Reference))

內存 enc ID 足夠 phantom 強引用 進行 溢出 tom 簡單談談引用(摘自java虛擬機第二版 ) 署名:wander 一、四種引用   在JDK 1.2之後,Java對引用的概念進行了擴充,將引用分為強引用(Strong Reference)、軟

Java基礎篇 - 引用引用引用引用

splay 查看 tla 之前 for 應用 幹貨 程序 策略 前言 Java執行GC判斷對象是否存活有兩種方式其中一種是引用計數。 引用計數:Java堆中每一個對象都有一個引用計數屬性,引用每新增1次計數加1,引用每釋放1次計數減1。 在JDK 1.2以前的版本中,若

Java 引用引用引用引用

參考來源:http://www.cnblogs.com/dolphin0520/p/3784171.html  感謝原作者的分享!!! 以下內容是本人在看完之後按照自己的理解複述的,僅作為學習記錄,欲知詳解請點選上面的網址。 1.強引用 示例:Object object=new

JAVA基礎:引用引用引用引用

生活 任何傻瓜都能寫出計算機可以理解的程式碼。好的程式設計師能寫出人能讀懂的程式碼。 前言 在JAVA中,開發人員不需要像C開發人員那樣手動去管理記憶體中物件的生命週期,但是如果需要某些物件具備一定的生命週期(當記憶體不足的時候可以回收一些沒有必要的物件,從而規避一些OOM的風險

Java中的引用引用引用引用

在讀ThreadLocal原始碼的時候遇到了WeakReference,然後就仔細學習引用方面的知識,現在轉載一篇部落格。。 一.瞭解 強引用、軟引用、弱引用、虛引用的概念 在Java中,雖然不需要程式設計師手動去管理物件的生命週期,但是如果希望某些物件具備一定

Java引用引用引用引用深入探討

強引用、軟引用、弱引用和虛引用深入探討 為了更靈活的控制物件的生命週期,在JDK1.2之後,引用被劃分為強引用、軟引用、弱引用、虛引用四種類型,每種型別有不同的生命週期,它們不同的地方就在於垃圾回收器對待它們會使用不同的處理方式。 引用型別在日常開發中並不常關注,也很少注意到,因此很多人忽略了它們的存在,

四種引用型別:引用引用引用引用

java中除了基本資料型別的變數(int、long等),剩下的都是引用型別的變數,一共有四種不同的引用型別。 一、強引用(Strong Reference) 強引用就是最常見的對某個物件的引用,如下程式碼變數o就是對所建立的Object物件的一個強引用。 Object

引用(案例)

前言:如果只是想避免OutOfMemory異常的發生,則可以使用軟引用。如果對於應用的效能更在意,想盡快回收一些佔用記憶體比較大的物件,則可以使用弱引用。 1.強引用(StrongReference)   強引用就是指在程式程式碼之中普遍存在的,比如下面程式碼中的

java中引用引用弱應用引用

虛引用:“虛引用”顧名思義,就是形同虛設,與其他幾種引用都不同,虛引用並不會決定物件的生命週期。如果一個物件 僅持有虛引用,那麼它就和沒有任何引用一樣,在任何時候都可能被垃圾回收。 虛引用主要用來跟蹤物件被垃圾回收的活動。虛引用與軟引用和弱引用的一個區別在於:虛引用必須和引用佇列 (ReferenceQue

JAVA的四種引用型別的作用——引用引用引用引用

java有四種引用型別,分別是強引用、軟引用、弱引用、虛引用。 背景:我們希望有這樣一種場景像快取一樣, 即:在記憶體還足夠時,希望能夠保留這些物件,當記憶體不夠時,則刪除這些物件(當然是由垃圾回收完成)。 四種引用的強度:強引用(Strong Reference)>軟引用(Sof

軟弱---引用引用引用引用

1、概述    在JDK1.2以前的版本中,當一個物件不被任何變數引用,那麼程式就無法再使用這個物件。也就是說,只有物件處於可觸及狀態,程式才能使用它。這 就像在日常生活中,從商店購買了某樣物品後,如果有用,就一直保留它,否則就把它扔到垃圾箱,由清潔工人收走。一般