前段时间我使用软引用创建了一个缓存,但是在试图解决一个错误时,我担心实际上我做了不正确的操作,并且在它不应该删除对象时,吨。这就是我已经做到了:这是使用软参考的正确方法
private static final Map<String, SoftReference<Buffered>> imageMap =
new HashMap<String,SoftReference<Buffered>>();
public static synchronized Buffered addImage(String sum, final byte[] imageData)
{
SoftReference<Buffered> bufferedRef = imageMap.get(sum);
Buffered buffered;
if (bufferedRef!=null)
{
//There are no longer any hard refs but we need again so add back in
if(bufferedRef.get()==null)
{
buffered = new Buffered(imageData, sum);
imageMap.put(sum, new SoftReference(buffered));
}
else
{
buffered=bufferedRef.get();
}
}
else
{
buffered = new Buffered(imageData, logDescriptor, sum);
imageMap.put(sum, new SoftReference(buffered));
}
return buffered;
}
public static Buffered getImage(String sum)
{
SoftReference<Buffered> sr = imageMap.get(sum);
if(sr!=null)
{
return sr.get();
}
return null;
}
这样的想法是调用进程可以添加可identifed新的缓冲对象/抬头通过密钥总和,那么只要这个缓冲对象正在使用通过至少一个对象它不会被从地图中移除,但是如果它不再被任何对象使用,那么如果内存变得紧张,它可能是垃圾收集。
但在我的代码现在期待的是,在关键领域的总和总是被引用别的地方最重要的事情(这是不一定的情况下)
编辑:所以,我想Colin的解决方案,但我是那种因为putIfAbsent()似乎没有返回附加值,所以难倒了。我修改了addImage方法来获取一些调试
public static synchronized Buffered addImage(String sum, final byte[] imageData)
{
Buffered buffered = new Buffered(imageData, sum);
Buffered buffered2 = imageMap.get(sum);
Buffered buffered3 = imageMap.putIfAbsent(sum,buffered);
Buffered buffered4 = imageMap.get(sum);
System.out.println("Buffered AddImage1:"+buffered);
System.out.println("Buffered AddImage2:"+buffered2);
System.out.println("Buffered AddImage3:"+buffered3);
System.out.println("Buffered AddImage4:"+buffered4);
return buffered2;
}
回报
Buffered AddImage1:[email protected]
Buffered AddImage2:null
Buffered AddImage3:null
Buffered AddImage4:[email protected]
所以这清楚地表明缓冲的情况下是不存在下手,并成功构建了补充,但肯定应该返回通过putIfAbsent?
究竟是什么问题? 此外,getImage也应该同步,并且代码中存在内存泄漏(所收集引用的条目未被释放)。 – Kru 2010-11-17 21:27:05
Chris:我的问题是可以删除一个Buffered类的实例,但仍然在我的代码中引用某处,我不明白你的内存泄漏点。 – 2010-11-17 22:35:43