2014-02-17 28 views
1

之間的不同,我覺得在這個link 文檔它描述如下:什麼的WeakReference和SoftReference的

弱引用是應該有自己的條目自動刪除,一旦他們不被引用的話(從外部)的映射有用。 SoftReference和WeakReference之間的差異是決定清除和排隊參考的時間點: SoftReference應該儘可能晚地被清除並排入隊列,也就是說,如果VM存在內存不足。 WeakReference可能會被清除並在已知被弱引用時立即入列。

但是當我查看Dalvikvm的源代碼時,發現了dvmCollectGarbageInternal(Heap.cpp L446 Android 4.4)函數中的一些東西。看起來有兩個引用是 在同一時間清除。

/* 
* All strongly-reachable objects have now been marked. Process 
* weakly-reachable objects discovered while tracing. 
*/ 
dvmHeapProcessReferences(&gcHeap->softReferences, 
         spec->doPreserve == false, 
         &gcHeap->weakReferences, 
         &gcHeap->finalizerReferences, 
         &gcHeap->phantomReferences); 

我想念什麼?

============================================== ==================================

在@ fadden的幫助下,我找到了代碼

if (!marked && ((++counter) & 1)) 

的dalvikvm儲備的一半sofereference每個GC過程中,我複製別人的測試代碼測試

最終的ArrayList>列表=新的ArrayList>( SR_COUNT);對於(int i = 0; i < SR_COUNT; ++ i){ list.add(new SoftReference(new Integer(i))); }

/* Test */ 
    for (int i = 0; i < 3; ++i) { 
     System.gc(); 

     try { 
      Thread.sleep(200); 
     } catch (final InterruptedException e) { 
     } 
    } 

    /* Check */ 
    int dead = 0; 
    for (final SoftReference<Integer> ref : list) { 
     if (ref.get() == null) { 
      ++dead; 
     } 
     Log.d(TAG, "dead: " + dead); 
    } 

來自logcat的所有日誌都是我的想法。

回答

0

從認識弱引用,由伊桑·尼古拉斯: https://weblogs.java.net/blog/enicholas/archive/2006/05/understanding_w.html

弱引用

弱引用,簡單地說,是不是強大到足以迫使對象保留在內存中的參考。弱引用使您可以利用垃圾收集器爲您確定可達性的能力,因此您無需自己動手。你創建一個這樣的弱引用:

WeakReference weakWidget = new WeakReference(widget);

然後在代碼中的其他地方可以使用weakWidget.get()來獲取實際的Widget對象。當然,弱引用不足以防止垃圾收集,因此您可能會發現(如果沒有強引用的小部件)weakWidget.get()突然開始返回null。

...

軟引用

軟引用是酷似一個弱引用,但它不太急於扔掉它所指的對象。只有弱可達性的對象(對它的最強引用是WeakReferences)將在下一次垃圾回收循環中被丟棄,但是可以輕鬆訪問的對象通常會持續一段時間。

SoftReferences的行爲與WeakReferences的行爲不同,但在實踐中,只要內存豐富,可以輕鬆訪問軟對象。這使得它們成爲高速緩存的良好基礎,例如上面描述的圖像高速緩存,因爲您可以讓垃圾回收器擔心對象的可訪問性(永遠不會從緩存中刪除強可到達的對象)以及它有多糟糕需要他們消耗的內存。

彼得·凱斯勒加入評論:

太陽JRE並不同於在WeakReferences治療SoftReferences。如果可用內存沒有壓力,我們試圖保留由SoftReference引用的對象。一個細節:「客戶端」和「服務器」JRE的策略是不同的:客戶端JRE試圖通過清除SoftReferences而不是擴展堆來保持足跡小,而服務器JRE會盡量保持您的性能高,喜歡擴大堆(如果可能),而不是清除SoftReferences。一種尺寸不適合所有。

2

FWIW,Java中弱/軟/幻像引用的最佳描述在The Java Programming Language(「Garbage Collection and Memory」)的第17章中。

對於軟引用保留沒有規定的策略。虛擬機允許在GC期間丟棄全部或全部,或者其間的任何內容。唯一的要求是虛擬機應該在拋出OOM之前丟棄所有可輕鬆訪問的對象。

您可以在的MarkSweep.cpp中繼續Dalvik的邏輯。特別注意撥打preserveSomeSoftReferences(),它保留了一些,但不是基於「顏色」的參考。您可以在wikipedia GC article上閱讀更多關於顏色的內容。

+0

你說得對。我找到了保留碼「if(!marked &&((++ counter)&1))」。dalvikvm保留每個GC程序 – jerry

+1

的一半參照。無論系統的狀態如何,每個GC都會丟失一半軟引用。對應用程序開發人員不太有用。 – fadden

+0

但是爲什麼?爲什麼不使用FILO,我認爲那會更好地讓程序保持它所需要的 – jerry

相關問題