強(strong)、軟(soft)、弱(weak)、虛(phantom)引用

https://github.com/Androooid/treasure/blob/master/source/lightsky/posts/mat_usage.mdjava

1.1 GC Root

JAVA虛擬機經過可達性(Reachability)來判斷對象是否存活,基本思想:以"GC Roots"的對象做爲起始點向下搜索,搜索造成的路徑稱爲引用鏈,當一個對象到GC Roots沒有任何引用鏈相連(即不可達的),則該對象被斷定爲能夠被回收的對象,反之不能被回收。git

GC Roots能夠是如下任意對象github

  • 一個在current thread(當前線程)的call stack(調用棧)上的對象(例如方法參數和局部變量)
  • 線程自身或者system class loader(系統類加載器)加載的類
  • native code(本地代碼)保留的活動對象

1.2 內存泄漏

對象無用了,但仍然可達(未釋放),垃圾回收器沒法回收。web

1.3 強(strong)、軟(soft)、弱(weak)、虛(phantom)引用

Strong references

普通的java引用,咱們一般new的對象就是: StringBuffer buffer = new StringBuffer(); 若是一個對象經過一串強引用鏈可達,那麼它就不會被垃圾回收。你確定不但願本身正在使用的引用被垃圾回收器回收吧。但對於集合中的對象,應在不使用的時候移除掉,不然會佔用更多的內存,致使內存泄漏。緩存

Soft reference

當對象是Soft reference可達時,gc會向系統申請更多內存,而不是直接回收它,當內存不足的時候纔回收它。所以Soft reference適合用於構建一些緩存系統,好比圖片緩存。函數

WeakReference

WeakReference不會強制對象保存在內存中。它擁有比較短暫的生命週期,容許你使用垃圾回收器的能力去權衡一個對象的可達性。在垃圾回收器掃描它所管轄的內存區域過程當中,一旦gc發現對象是weakReference可達,就會把它放到ReferenceQueue中,等下次gc時回收它。 WeakReference<Widget> weakWidget = new WeakReference<Widget>(widget); 系統爲咱們提供了WeakHashMap,和HashMap相似,只是其key使用了weak reference。若是WeakHashMap的某個key被垃圾回收器回收,那麼entity也會自動被remove。post

因爲WeakReference被GC回收的可能性較大,所以,在使用它以前,你須要經過weakObj.get()去判斷目的對象引用是否已經被回收..net

Reference queque

一旦WeakReference.get()返回null,它指向的對象就會被垃圾回收,那麼WeakReference對象就沒有用了,意味着你應該進行一些清理。好比在WeakHashMap中要把回收過的key從Map中刪除掉,避免無用的的weakReference不斷增加。 ReferenceQueue可讓你很容易地跟蹤dead references。WeakReference類的構造函數有一個ReferenceQueue參數,當指向的對象被垃圾回收時,會把WeakReference對象放到ReferenceQueue中。這樣,遍歷ReferenceQueue能夠獲得全部回收過的WeakReference。線程

Phantom reference

和soft,weak Reference區別較大,它的get()方法老是返回null。這意味着你只能用PhantomReference自己,而得不到它指向的對象。當WeakReference指向的對象變得弱可達(weakly reachable)時會當即被放到ReferenceQueue中,這在finalization、garbage collection以前發生。理論上,你能夠在finalize()方法中使對象「復活」(使一個強引用指向它就好了,gc不會回收它)。但無法復活PhantomReference指向的對象。而PhantomReference是在garbage collection以後被放到ReferenceQueue中的,無法復活。code

關於Phantom reference的更多討論,請參考:understanding-weak-references

相關文章
相關標籤/搜索