2011-04-22 148 views
10

我正在爲我的Android應用程序實現緩存機制。SoftReference太早收集垃圾

我使用SoftReference,就像我找到的許多例子。問題是,當我在我的ListView中向上或向下滾動時,圖像的大多數已被清除。我可以在LogCat中看到,每次應用程序加載新圖像時,我的應用程序都會被垃圾收集。這意味着ListView中不可見圖像的大多數都消失了。

所以,每次我回捲到一個較早的位置(我真的下載的圖片前)我不得不再次下載圖像 - 他們不緩存

我也研究過這個話題。 According to Mark Murphy in this article,似乎有(或是?)與SoftReference的錯誤。其他一些結果表明同樣的事情(或相同的結果); SoftReference s正在清理得太早。

有什麼工作方案嗎?

+2

**太**早?如果需要記憶,它將被清除。誰說它太早?如果系統想要清除它,這就是softreference的用法。 – binnyb 2011-04-22 17:11:14

+0

正確。但是不需要更多的記憶,因爲我可以輕鬆地在內存中容納大約50張圖像。但爲了避免OOM錯誤,我需要使用這種緩存機制。 – Wroclai 2011-04-22 17:12:52

+0

我建議你緩存每張圖片,這種方式當它被清除時,你不必從網頁上獲取它(除非它不存在於緩存中) – binnyb 2011-04-22 17:15:47

回答

16

SoftReference是窮人的緩存。 JVM可以更長時間地保存這些引用,但不一定。只要沒有硬引用,JVM就可以垃圾收集軟引用的對象。您所遇到的JVM的行爲是正確的,因爲JVM不必長時間持有這樣的對象。當然,大多數JVM試圖在一定程度上保持軟參考對象的活性。

因此,SoftReferences是一種危險的緩存。如果你真的想確保緩存行爲,你需要一個真正的緩存。像LRU-cache一樣。特別是如果你的緩存對性能至關重要,你應該使用適當的緩存。

+0

明確答案!謝謝!我將研究LRU緩存,看看它是我想要的。但是爲什麼JVM不把軟引用「稍長一點」?實際上有剩餘的內存... – Wroclai 2011-04-22 17:27:43

+3

因爲它不必。您對SR合同的理解不正確。 GC不希望延遲清理SR到OOM時刻,因爲它可能根本沒有時間去做,而不會影響應用程序的性能。 – 2011-04-22 17:55:53

+0

@ yamburg:謝謝你清理! – Wroclai 2011-04-22 17:59:46

2

緩存永久存儲器上的每個圖像,而不是隻在內存中。

+0

瞬態緩存的持久存儲?對。這是一個解決方案。對於其他一些問題。 – 2011-04-22 17:57:34

+0

這不完全清楚,這需要是一個瞬態緩存。 – 2011-04-22 18:01:13

1

甘美的回答在你的情況下是正確的。然而,對於更多的信息,請參閱GC FAQ,質疑32

雖然Java HotSpot服務器VM採用了最大可能的堆大小(由-Xmx選項設置)來計算剩餘的可用空間。

Java HotSpot Client VM使用當前堆大小來計算可用空間。

這意味着服務器虛擬機的一般傾向是增加堆而不是刷新軟引用,因此-Xmx在軟引用被垃圾收集時具有顯着影響。

+1

請注意,Android應用程序不會在JVM中執行。 – Jan 2012-01-15 17:30:23

+0

理想情況下,Android會至少保留軟引用至少一點,但事實上,您使用SoftReference來表示您不介意數據是否消失,並基本立即刪除。 JVM正確執行此操作。 Android基本上用垃圾收集器來吃東西。所以JVM常問問題比上述問題更有意義。其中的答案基本上是使用強有力的參考。 – Tatarize 2015-02-10 06:50:00

7

從Android的培訓網站:

http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html

在過去,一個流行的內存緩存實現是 或WeakReference的位圖緩存,然而這並不建議SoftReference的。 從Android 2開始。3(API級別9)垃圾收集器更積極地收集軟/弱引用,這使得它們 相當無效。另外,在Android 3.0(API級別11), 之前,位圖的後備數據被存儲在本地存儲器中,該存儲器不是以可預測的方式釋放的 ,可能導致應用程序 短暫超出其存儲器限制和崩潰。

鏈接中的更多信息。

我們應該用LruCache代替。

+0

謝謝!我會在下次考慮! – Wroclai 2012-08-13 11:57:30