我不是要談的java.lang.ref包中可用的每個引用類,因為它已經是很好的解釋在這里 。 讓我們看一下我編寫的以下代碼片段,以了解WeakReference的基本操作。
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map; public class ReferencesTest { private WeakReference<Map<Integer, String>> myMap; public static void main(String[] args) { new ReferencesTest().doFunction(); } private void doFunction() { Map<Integer, String> map = new HashMap<Integer, String>(); myMap = new WeakReference<Map<Integer, String>>(map); map = null; int i = 0; while (true) { if (myMap != null && myMap.get() != null) { myMap.get().put(i++, "test" + i); System.out.println("im still working!!!!"); } else { System.out .println("*******im free*******"); } } }
}
首先,我定義了一個弱引用實例變量,向其分配在doFunction()方法中初始化的HashMap實例。 然后,數據通過弱引用實例而不是直接通過我們創建的哈希圖的具體實例輸入到地圖。 由于WeakReferences的工作方式,我們檢查地圖是否為空。
在程序執行期間,如果沒有軟引用或強引用綁定到弱引用,則將首先對其進行垃圾收集。 因此,如果內存相當低,或者垃圾收集器認為適當的時間和時間,則弱引用是垃圾收集,這就是為什么我在代碼中包含else語句以顯示這種情況的原因。 通過設置最小–Xms和–Xmx來運行它,以了解其工作原理,因為否則您將不得不等待更長的時間才能獲得內存不足異常。 然后將WeakReference實現更改為SoftReference實現,并查看程序在幾次迭代后實際上崩潰了。 這是由于SoftReferences僅保證在發生OutOfMemory錯誤之前清理內存。 但是,有了WeakReference,該程序就可以繼續運行而不會暫停,因為它幾乎總是可以進行垃圾回收,并且我們可以重新初始化緩存并繼續填充緩存。
關于弱引用的好處是,在我看來,這是實現內存中緩存的最佳方法之一,當我們需要保留數據不經常更改但經常在內存中訪問且成本高昂時,通常會自行實現對于像JBoss緩存或EHCache這樣的成熟的緩存實現而言,這實在太多了。 通常,我已經實現了緩存解決方案,還看到了類似于以下代碼段的生產代碼。
import java.util.HashMap;
import java.util.Map; public class CacheTest { private Map<String, Object> myAwesomeCache = new HashMap<String, Object>(100); public Object getData(String id){ Object objToReturn = null; if(myAwesomeCache.containsKey(id)){ objToReturn = myAwesomeCache.get(id); }else{ // retrieve from the database and populate the in memory cache map } return objToReturn; }
}
這只是一個非常基本的級別的實現,它可以使我們有時會使用Maps來構建內存緩存實現。 我們必須注意的事實是,盡管此實現沒有本質上的錯誤,但是在您的應用程序內存不足的情況下,如果垃圾回收器可以將其從內存中刪除以釋放一些內存,這將是理想的選擇其他需要它的過程。 但是,由于此映射是一個強大的參考,因此垃圾回收器無法將此參考標記為符合收集條件。 更好的解決方案是將緩存實現從HashMap更改為WeakHashMap 。
Javadoc指定了有關WeakHashMap的以下內容;
“基于哈希表的具有弱鍵的Map實現。 如果WeakHashMap中的條目不再是普通使用的鍵,它將自動被刪除。 更準確地說,給定鍵的映射的存在不會阻止該鍵被垃圾收集器丟棄,即被終結化,終結和回收。 當一個鍵被丟棄時,它的條目會被有效地從映射中刪除,因此此類的行為與其他Map實現有所不同。”
因此,回想起來,我相信只要您需要內存中的緩存實現,并且內存對您而言至關重要,那么使用WeakHashMap將會是有益的。
總結了我對參考資料包的發現,并邀請大家分享您在這方面的經驗,對此深表感謝。
干杯
參考:在“ 我的旅程” IT博客中,從我們的JCG合作伙伴 Dinuka Arseculeratne 了解Java弱引用
翻譯自: https://www.javacodegeeks.com/2012/01/understanding-java-weak-references.html