我在使用Google-guava中的MapMaker時遇到問題。下面是代碼:google-guava MapMaker .softValues() - 值不會被GC編輯,OOME:堆空間如下
package test;
import java.lang.ref.SoftReference;
import java.util.Map;
import java.util.Random;
import com.google.common.collect.MapEvictionListener;
import com.google.common.collect.MapMaker;
public class MapMakerTest {
private static Random RANDOM = new Random();
private static char[] CHARS =
("abcdefghijklmnopqrstuvwxyz" +
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
"[email protected]#$%^&*()_+").toCharArray();
public static void main(String[] args) throws Exception {
MapEvictionListener<String, String> listener = new MapEvictionListener<String, String>() {
@Override
public void onEviction(String key, String value) {
System.out.println(">>>>> evicted");
}
};
Map<String, String> map = new MapMaker().
concurrencyLevel(1).softValues().
evictionListener(listener).makeMap();
while (true) {
System.out.println(map.size());
String s = getRandomString();
map.put(s, s);
Thread.sleep(50);
}
}
private static String getRandomString() {
int total = 50000;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < total; ++i) {
sb.append(CHARS[RANDOM.nextInt(CHARS.length)]);
}
return sb.toString();
}
}
當Java是叫這樣的:java -Xms2m -Xmx2m -cp guava-r09.jar:. test.MapMakerTest
(堆設置是如此之小,故意容易看看會發生什麼)圍繞它的OutOfMemoryError爆炸60迭代:HeapSpace。
但是,當地圖是Map<String, SoftReference<String>>
(並根據其餘代碼的變化:監聽者和put),我可以看到驅逐發生,代碼簡單地工作,並且值被垃圾收集。
在所有文檔中,包括這一個:http://guava-libraries.googlecode.com/svn/tags/release09/javadoc/index.html,都沒有明確提及SoftReferences。當調用put時,Map實現是否應該包含SoftReference中的值?我對這個假設的用法感到困惑。
我懷疑番石榴r09。
任何人都可能解釋我做錯了什麼,以及爲什麼我的假設是錯誤的?
最好的問候, wujek
它工作時,我讓你提到的變化,這讓很多的意義。但是,爲什麼它能夠直接使用SoftReference作爲值呢? 謝謝你的回答! – wujek
哦,我想我明白了。該值實際上是SoftReference>並被收集,因此整個條目也被收集。 –
wujek