簡體   English   中英

什么時候應該使用弱引用?

[英]When should weak references be used?

我最近遇到了一段帶有WeakReferences的Java代碼 - 我從未見過它們已部署,盡管我們在介紹時遇到過它們。 這是應該常規使用的東西還是只有在遇到內存問題時? 如果是后者,它們是否可以輕松改裝或代碼是否需要嚴格的重構? 普通的Java(或C#)程序員通常會忽略它們嗎?

編輯過度使用WR可以造成任何損害嗎?

弱引用都是關於垃圾收集。 標准對象在所有對它的引用被切斷之前不會“消失”,這意味着在垃圾收集將其視為垃圾之前,必須刪除各種對象必須刪除的所有引用。

僅僅因為您的對象被其他對象引用而使用弱引用並不一定意味着它不是垃圾。 它仍然可以被GC拾取並從內存中刪除。

一個例子:如果我的應用程序中有一堆Foo對象,我可能想使用Set來保存我所有Foo的中心記錄。 但是,當我的應用程序的其他部分通過刪除對它的所有引用來刪除Foo對象時,我不希望我的Set的剩余引用保留到該對象以防止它被垃圾收集! 真的,我只是希望它從我的集合中消失。 這就是你使用類似弱集(Java有一個WeakHashMap)的東西,它使用對其成員的弱引用而不是“強”引用。

如果您的對象在您想要它們時沒有被垃圾收集,那么您在簿記中出錯了,還有一些內容仍然存在您忘記刪除的引用。 使用弱引用可以緩解這種記帳的痛苦,因為你不必擔心他們保持一個對象“活着”,並取消垃圾收集,但你沒有使用它們。

只要您想要對對象進行引用而不自己保持對象存活,就可以使用它們。 這對於許多類似緩存的功能來說都是如此,但在事件處理中也起着重要作用,訂閱者不應通過訂閱事件來保持活躍。

一個小例子:一個刷新一些數據的計時器事件。 任何數量的對象都可以在計時器上訂閱以獲得通知,但是他們在計時器上訂閱的這個事實不應該使它們保持活動狀態。 所以計時器應該對對象有弱引用。

過度熱情地使用WR可以造成任何損害嗎?

是的,它可以。

一個問題是弱引用會使您的代碼更復雜並且可能容易出錯。 任何使用弱引用的代碼都需要處理每次使用它時引用被破壞的可能性。 如果過度使用弱引用,最終會編寫大量額外代碼。 (您可以通過隱藏負責檢查的方法后面的每個弱引用來緩解這種情況,並根據需要重新創建丟棄的對象。但這可能不一定那么簡單;例如,如果重新創建過程涉及網絡訪問,你需要應對重新創建失敗的可能性。)

第二個問題是使用弱引用存在運行時開銷。 顯而易見的成本是創建弱引用和調用get 不太明顯的成本是每次GC運行時都需要進行大量的額外工作。

最后一個問題是,如果您對應用程序很可能在將來需要的某些內容使用弱引用,則可能會產生重復重新創建它的成本。 如果此成本很高(就CPU時間,IO帶寬,網絡流量而言),您的應用程序可能會因此而表現不佳。 你可能最好給JVM提供更多內存,而根本不使用弱引用。

當然,這並不意味着你應該完全避免使用弱引用。 只是你需要仔細思考。 您可能應首先在應用程序上運行內存分析器,以確定內存使用問題源於何處。

在考慮使用WeakReference時要問的一個很好的問題是,如果弱引用在對象存在的強引用中無效,人們會感覺如何。 如果這會使WeakReference不那么有用,那么WeakReference可能不是最好用的。 如果這將是對垃圾收集產生的非確定性失效的改進,那么WeakReference可能是正確的選擇。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM