google-guava MapMaker .softValues() - 值没有得到GC-ed,OOME:HeapSpace如下

时间:2011-08-04 17:54:25

标签: java guava soft-references

我在使用google-guava的MapMaker时遇到问题。这是代码:

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" +
     "1234567890-=!@#$%^&*()_+").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();
}
}

在第60次迭代的过程中,当java被调用为:java -Xms2m -Xmx2m -cp guava-r09.jar:. test.MapMakerTest(堆设置很小,以便更容易看到会发生什么)时,它会爆发出OutOfMemoryError:HeapSpace。

但是,当地图为Map<String, SoftReference<String>>时(并根据其余代码的变化:监听器和放置),我可以看到发生的驱逐,代码只是起作用,而值收集垃圾。

在所有文档中,包括这一个:http://guava-libraries.googlecode.com/svn/tags/release09/javadoc/index.html,没有明确提及SoftReferences。当调用put时,Map实现是否应该包装SoftReference中的值?我对所谓的用法感到很困惑。

我正在怀着番石榴r09。

任何人都可以解释我做错了什么,为什么我的假设是错误的?

祝你好运, wujek

1 个答案:

答案 0 :(得分:3)

您对密钥和值使用相同的对象,因此它可以作为密钥强烈访问,并且不符合垃圾回收的条件,尽管可以轻松访问值:

map.put(s, s); 

尝试使用不同的实例:

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