2011-08-04 27 views
1

我在使用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

回答

3

可以使用相同的對象鍵和值,因此它是作爲重點強可,不符合垃圾收集儘管價值是軟可:

map.put(s, s); 

嘗試使用不同的實例:

map.put(s, new String(s)); 
+0

它工作時,我讓你提到的變化,這讓很多的意義。但是,爲什麼它能夠直接使用SoftReference作爲值呢? 謝謝你的回答! – wujek

+0

哦,我想我明白了。該值實際上是SoftReference >並被收集,因此整個條目也被收集。 – wujek