https://github.com/Androooid/treasure/blob/master/source/lightsky/posts/mat_usage.mdjava
JAVA虛擬機經過可達性(Reachability)來判斷對象是否存活,基本思想:以"GC Roots"的對象做爲起始點向下搜索,搜索造成的路徑稱爲引用鏈,當一個對象到GC Roots沒有任何引用鏈相連(即不可達的),則該對象被斷定爲能夠被回收的對象,反之不能被回收。git
GC Roots能夠是如下任意對象github
對象無用了,但仍然可達(未釋放),垃圾回收器沒法回收。web
普通的java引用,咱們一般new的對象就是: StringBuffer buffer = new StringBuffer();
若是一個對象經過一串強引用鏈可達,那麼它就不會被垃圾回收。你確定不但願本身正在使用的引用被垃圾回收器回收吧。但對於集合中的對象,應在不使用的時候移除掉,不然會佔用更多的內存,致使內存泄漏。緩存
當對象是Soft reference可達時,gc會向系統申請更多內存,而不是直接回收它,當內存不足的時候纔回收它。所以Soft reference適合用於構建一些緩存系統,好比圖片緩存。函數
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
一旦WeakReference.get()返回null,它指向的對象就會被垃圾回收,那麼WeakReference對象就沒有用了,意味着你應該進行一些清理。好比在WeakHashMap中要把回收過的key從Map中刪除掉,避免無用的的weakReference不斷增加。 ReferenceQueue可讓你很容易地跟蹤dead references。WeakReference類的構造函數有一個ReferenceQueue參數,當指向的對象被垃圾回收時,會把WeakReference對象放到ReferenceQueue中。這樣,遍歷ReferenceQueue能夠獲得全部回收過的WeakReference。線程
和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