說說WeakReference弱引用


WeakReference弱引用概述

http://www.cnblogs.com/xrq730/p/4836700.html,關於Java的四種引用狀態具體請參看此文

Java里一個對象obj被創建時,被放在堆里。當GC運行的時候,發現沒有任何引用指向obj,那么就會回收obj對象的堆內存空間。

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

Object obj = new Object();

obj = null;

這種方式說可以吧,也不是不可以,但是對於程序員來說,這是一件繁瑣而且未被自動回收理念的。手動置空不應該需要程序員來做的,因為對於一個簡單的對象而言,當調用它的方法執行完畢,引用會自動從棧中彈出,這樣下一次GC的時候就會自動回收這塊內存了。

但是有例外。比如說緩存,由於緩存對象是程序需要的,那么只要程序正在運行,緩存中的引用是不會被GC的,隨着緩存中的引用越來越多,GC無法回收的對象也越來越多,無法被自動回收。當這些對象需要被回收時,回收這些對象的任務只有交給程序員了,然而這卻違背了GC的本質----自動回收。

所以Java中引入了弱引用WeakReference。

 

WeakReference弱引用示例

下面演示一下WeakReference簡單的使用,首先定義一個實體類:

public class Car
{
    private double     price;
    private String    color;
    
    public Car(double price, String color)
    {
        this.price = price;
        this.color = color;
    }
    
    public double getPrice()
    {
        return price;
    }

    public String getColor()
    {
        return color;
    }

    public String toString()
    {
        return "This car is a " + this.color + " car, costs $" + price;
    }
}

一般使用WeakReference的時候都會定義一個類繼承自WeakReference,在這個類中再定義一些別的屬性,這里就不定義別的屬性了:

public class WeakReferenceCar extends WeakReference<Car>
{
    public WeakReferenceCar(Car car)
    {
        super(car);
    }
}
public class WeakReferenceCar extends WeakReference<Car>
{
    public WeakReferenceCar(Car car)
    {
        super(car);
    }
}

main函數調用一下,當然為了更清楚地看到GC的效果,設置虛擬機參數"-XX:+PrintGCDetails":

public static void main(String[] args)
    {
        Car car = new Car(2000.0, "red");
        WeakReferenceCar wrc = new WeakReferenceCar(car);
        wrc.setStr("111");
        int i = 0;
        while (true)
        {
            if (wrc.get() != null)
            {
                i++;
                System.out.println("WeakReferenceCar's Car is alive for " + i + ", loop - " + wrc);
            }
            else
            {
                System.out.println("WeakReferenceCar's Car has bean collected");
                break;
            }
        }
    }

看一下運行結果:

WeakReferenceCar's Car is alive for 22880, loop - com.xrq.test14.WeakReferenceCar@5d888759
WeakReferenceCar's Car is alive for 22881, loop - com.xrq.test14.WeakReferenceCar@5d888759
WeakReferenceCar's Car is alive for 22882, loop - com.xrq.test14.WeakReferenceCar@5d888759
WeakReferenceCar's Car is alive for 22883, loop - com.xrq.test14.WeakReferenceCar@5d888759
WeakReferenceCar's Car is alive for 22884, loop - com.xrq.test14.WeakReferenceCar@5d888759
[GC [PSYoungGen: 16400K->256K(18688K)] 16400K->256K(61440K), 0.0002863 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
WeakReferenceCar's Car is alive for 22885, loop - com.xrq.test14.WeakReferenceCar@5d888759
WeakReferenceCar's Car has bean collected
Heap
 PSYoungGen      total 18688K, used 899K [0x0000000034180000, 0x0000000035650000, 0x0000000048f80000)
  eden space 16064K, 4% used [0x0000000034180000,0x0000000034220c30,0x0000000035130000)
  from space 2624K, 9% used [0x00000000353c0000,0x0000000035400000,0x0000000035650000)
  to   space 2624K, 0% used [0x0000000035130000,0x0000000035130000,0x00000000353c0000)
 PSOldGen        total 42752K, used 0K [0x000000000a580000, 0x000000000cf40000, 0x0000000034180000)
  object space 42752K, 0% used [0x000000000a580000,0x000000000a580000,0x000000000cf40000)
 PSPermGen       total 21248K, used 3016K [0x0000000005180000, 0x0000000006640000, 0x000000000a580000)
  object space 21248K, 14% used [0x0000000005180000,0x0000000005472318,0x0000000006640000)

看到22884次循環之后,WeakReferenceCar關聯的對象Car被回收掉了,注意是弱引用關聯的對象car被回收,而不是弱引用本身wrc被回收。

 

其他

1、除了弱引用,還有軟引用。SoftReference(軟引用)和WeakReference的區別在於,假如下次GC的時候,發現內存沒有溢出,則不會回收SoftReference關聯的對象,但是對於WeakReference,在下一次GC的時候,一定會回收,無論內存是否滿。像緩存,其實最適合的個人認為應該是SoftReference,因為緩存里面的數據是運行時會用到的,能不回收就盡量不要去回收它們,而等到內存實在不夠的時候再去回收

2、WeakReference的父類Reference中有一個變量queue,是ReferenceQueue類型的。WeakReference中的構造函數中有一個兩個參數的構造函數,其中第二個參數就是這個ReferenceQueue,表示在WeakReference指向的對象被回收之后,可以利用ReferenceQueue來保存被回收的對象


免責聲明!

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



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