溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

weak reference的介紹

發布時間:2020-08-04 13:06:11 來源:網絡 閱讀:361 作者:shenshizhong 欄目:開發技術

對象回收條件:

Java, 當一個對象o被創建時, 它被放在堆里. GC運行的時候, 如果發現沒有任何引用指向o, o就會被回收. 也可以這么理解, 一個對象被回收, 必須滿足兩個條件: 1)沒有任何引用指向它 2)GC被運行.

置空處理:

在現實情況寫代碼的時候, 我們往往通過把所有指向某個對象的引用置空來保證這個對象在下次GC運行的時候被回收

例如:

Object c = new Car();

c=null;

但是, 手動置空對象對于程序員來說, 是一件繁瑣且違背自動回收的理念的.  對于簡單的情況, 手動置空是不需要程序員來做的, 因為在java, 對于簡單對象, 當調用它的方法執行完畢后, 指向它的引用會被從stack中彈出, 所以他就能在下一次GC執行時被回收了.

但是, 也有特殊例外. 當使用cache的時候, 由于cache的對象正是程序運行需要的, 那么只要程序正在運行, cache中的引用就不會被GC(或者說, cache中的reference擁有了和主程序一樣的life cycle). 那么隨著cache中的reference越來越多, GC無法回收的object也越來越多, 無法被自動回收. 當這些object需要被回收時, 回收這些object的任務只有交給程序編寫者了. 然而這卻違背了GC的本質(自動回收可以回收的objects).

weakreference的由來:

因為上面的原因, java中引入了weak reference(弱引用). 相對于前面舉例中的strong reference(強引用):Object c = new Car(); //只要c還指向car對象, car對象就不會被回收

但是 當一個對象僅僅被weak reference指向, 而沒有任何其他strong reference指向的時候, 如果GC運行, 那么這個對象就會被回收.

weakreference的使用

WeakReference<Car> weakCar = newWeakReference(Car)(car);

 當要獲得weak reference引用的object, 首先需要判斷它是否已經被回收:

weakCar.get();

 如果此方法為空, 那么說明weakCar指向的對象已經被回收了.

可回收例子:

package weakreference;

/**

 * @authorwison

 */

public class Car {

  privatedouble price;

  privateString colour;

 

  publicCar(double price, String colour){

    this.price= price;

    this.colour= colour;

  }

 

  publicdouble getPrice() {

    returnprice;

  }

  publicvoid setPrice(double price) {

    this.price= price;

  }

  publicString getColour() {

    returncolour;

  }

  publicvoid setColour(String colour) {

    this.colour= colour;

  }

 

  publicString toString(){

    returncolour +"car costs $"+price;

  }

 

}

package weakreference;

 

import java.lang.ref.WeakReference;

 

/**

 * @authorwison

 */

public class TestWeakReference {

 

 

  publicstatic void main(String[] args) {

   

    Carcar = new Car(22000,"silver");

    WeakReference<Car>weakCar = new WeakReference<Car>(car);

   

    inti=0;

   

    while(true){

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

       i++;

       System.out.println("Object is alive for "+i+" loops -"+weakCar);

     }else{

       System.out.println("Object has been collected.");

       break;

     }

    }

  }

 

}

在上例中, 程序運行一段時間后, 程序打印出"Object has been collected." 說明, weakreference指向的對象的被回收了.

值得注意的一點 , 即使有 car 引用指向對象,  car 是一個strong reference, weak reference weakCar指向的對象仍然被回收了. 這是因為java的編譯器在發現進入while循環之后, car 已經沒有被使用了, 所以進行了優化(將其置空?).

不可回收例子:

當把TestWeakReference.java修改為:

package weakreference;

 

import java.lang.ref.WeakReference;

 

/**

 * @authorwison

 */

public class TestWeakReference {

 

 

  publicstatic void main(String[] args) {

   

    Carcar = new Car(22000,"silver");

    WeakReference<Car>weakCar = new WeakReference<Car>(car);

   

    inti=0;

   

    while(true){

     System.out.println("here is the strong reference 'car' "+car);

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

       i++;

       System.out.println("Object is alive for "+i+" loops -"+weakCar);

     }else{

       System.out.println("Object has been collected.");

       break;

     }

    }

  }

 

}

 weak reference指向的object就不會被回收了. 因為還有一個strongreference car 指向它. WeakReference的一個特點是它何時被回收是不可確定的, 因為這是由GC運行的不確定性所確定的. 所以, 一般用weak reference引用的對象是:有價值被緩存, 而且很容易被重新被構建, 且很消耗內存的對象.

ReferenceQueue的簡單了解:

weak reference指向的對象被回收后, weak reference本身其實也就沒有用了. java提供了一個ReferenceQueue來保存這些所指向的對象已經被回收的reference. 用法是在定義WeakReference的時候將一個ReferenceQueue的對象作為參數傳入構造函數.

其他類型的references

SoftReference簡單了解:

soft reference(軟引用)和weakreference一樣, 但被GC回收的時候需要多一個條件: 當系統內存不足時, soft reference指向的object才會被回收. 正因為有這個特性, soft referenceweak reference更加適合做cache objectsreference. 因為它可以盡可能的retain cached objects, 減少重建他們所需的時間和消耗.

總之:

對象被回收條件:1)沒有任何引用指向它 2)GC被運行.

soft referenceweakreference,可以幫助我們更好的進行對象的回收。

 


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女