Java中的引用類型和垃圾回收

強引用Strong References
  強引用是最多見的引用:html

  好比:java

StringBuffer buffer = new StringBuffer();
  建立了一個StringBuffer類的對象,並用一個變量buffer存儲對這個對象的引用。這就是個強引用。程序員

  變量持有的是這個對象的引用。一般,引用是一個對象的存儲地址。api

  Java不像C或者C++同樣,Java沒有取地址符號&,也沒有解引用符號*或者->。緩存

  引用不一樣於指針,引用不能與整形進行互相轉換,也不能進行增減操做。markdown

  強引用是和垃圾回收機制相關的。oracle

  通常的,若是一個對象能夠經過一系列的強引用引用到,那麼就說明它是不會被垃圾回收機制(Garbage Collection)回收的。ide

  由於垃圾回收是不會回收你正在使用的對象的。性能

垃圾回收機制Garbage Collection
  若是一個對象,沒有一個引用指向它,那麼它就被認爲是一個垃圾。flex

  An object is considered garbage when there are no longer any references to it stored in any variables, the fields of any objects, or the elements of any arrays.

  在某一個時間,garbage collector將會發現成爲垃圾的對象,而後回收它所佔用的內存。

  C中用malloc()和free()來管理內存。

  C++是用new和delete來分配和管理內存空間。

  而Java使用garbage collection機制,不用程序員寫代碼管理,這樣會有一些性能上的影響,由於garbage collector會主動地回收內存。

  可是,GC機制減小了內存泄露,而且提升了程序員的效率。

何時強引用會太強了?
  有時候應用會使用一些不能被繼承的類,好比一個final的類,或者一個工廠方法返回的接口,並不知道有多少具體實現。

  而咱們想給這個類增長一個字段,好比給每個對象一個序列號,因而咱們用了HashMap,把這個類的對象做爲key,一個序列號做爲value。

  這時候咱們就必須100%肯定地知道一個特定對象的序列號何時再也不須要(好比對象的生命週期已經結束,就再也不須要它的序列號屬性),這樣咱們就能夠從map中移除它的entry。

  若是咱們在應當移除引用的時候沒有移除,垃圾回收將一直不會回收這個對象,引發內存泄露。

  而若是咱們過早地移除了咱們還在使用的對象的引用,又會發現本身丟失了信息。

  這些都是C/C++程序員常常會遇到的問題。而咱們用的是Java,咱們還要考慮這些,豈不是鬧複雜了?

  強引用另外一個常見的問題是緩存問題。

  比方說,圖像的緩存。圖像緩存應當阻止咱們重複載入圖像。

  因此圖像緩存保存有內存中已有的全部圖像的引用,若是使用一般的強引用,強引用自己會使得圖像一直存留在內存中,這樣就使得程序員像上面同樣,必須本身決定何時移除緩存中的引用,這樣對象才能被垃圾回收機制回收。

  這樣你就又放棄了讓GC本身管理垃圾回收的機制,而開始手動地管理內存。

引用對象類
  Java的引用對象類在包java.lang.ref下。

  http://docs.oracle.com/javase/7/docs/api/java/lang/ref/package-summary.html#package_description

  其中包含了三種顯式的引用類型(也便是Reference類的三個子類):

  SoftReference

  WeakReference

  PhantomReference

  一個引用對象(reference object)(即以上三種引用類型的對象)封裝了一個對其餘對象的引用(稱做referent)。

  引用對象提供了對referent的clean和get操做,可是不提供set操做。

  引用對象自己能夠像其餘通常的對象同樣被檢查和操縱。

  三種類型的引用定義了三種不一樣層次的可達性級別,由強到弱排列以下:

  SoftReference > WeakReference > PhantomReference

  越弱表示對垃圾回收器的限制越少,對象越容易被回收。

SoftReference
  SoftReference用來實現一些內存敏感的緩存(Soft references are for implementing memory-sensitive caches),只要內存空間足夠,對象就會保持不被回收。

  反之,當宿主進程的內存空間不足時,對象就會被GC回收。

  因此SoftReference意味着:hold on until you can’t.

WeakReference
  WeakReference能夠用來實現一些規範化映射(WeakHashMap),其中key或者value當它們再也不被引用時能夠自動被回收。

  當你想引用一個對象,可是這個對象有本身的生命週期,你不想介入這個對象的生命週期,這時候你就是用弱引用。

  這個引用不會在對象的垃圾回收判斷中產生任何附加的影響。

PlantomReference
  PlantomReference和WeakReference同樣,也不會介入引用對象的生命週期。

  PhantomReference用來調度一些預驗清理動做,提供比Java清理機制更靈活的處理方式。(Phantom references are for scheduling pre-mortem cleanup actions in a more flexible way than is possible with the Java finalization mechanism.)

  PlantomReference比較特殊,它的get方法老是返回null,因此你得不到它引用的對象。

  它保存ReferenceQueue中的軌跡。

  它容許你知道對象什麼時候從內存中移除。

相關文章
相關標籤/搜索