我不是要谈的java.lang.ref包中可用的每个引用类,因为它已经是很好的解释在这里 。 让我们看一下我编写的以下代码片段,以了解WeakReference的基本操作。
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;
public class ReferencesTest {
private WeakReference<Map<Integer, String>> myMap;
public static void main(String[] args) {
new ReferencesTest().doFunction();
}
private void doFunction() {
Map<Integer, String> map = new HashMap<Integer, String>();
myMap = new WeakReference<Map<Integer, String>>(map);
map = null;
int i = 0;
while (true) {
if (myMap != null && myMap.get() != null) {
myMap.get().put(i++, "test" + i);
System.out.println("im still working!!!!");
} else {
System.out
.println("*******im free*******");
}
}
}
}
首先,我定义了一个弱引用实例变量,向其分配在doFunction()方法中初始化的HashMap实例。 然后,数据通过弱引用实例而不是直接通过我们创建的哈希图的具体实例输入到地图。 由于WeakReferences的工作方式,我们检查地图是否为空。
在程序执行期间,如果没有软引用或强引用绑定到弱引用,则将首先对其进行垃圾收集。 因此,如果内存相当低,或者垃圾收集器认为适当的时间和时间,则弱引用是垃圾收集,这就是为什么我在代码中包含else语句以显示这种情况的原因。 通过设置最小–Xms和–Xmx来运行它,以了解其工作原理,因为否则您将不得不等待更长的时间才能获得内存不足异常。 然后将WeakReference实现更改为SoftReference实现,并查看程序在几次迭代后实际上崩溃了。 这是由于SoftReferences仅保证在发生OutOfMemory错误之前清理内存。 但是,有了WeakReference,该程序就可以继续运行而不会暂停,因为它几乎总是可以进行垃圾回收,并且我们可以重新初始化缓存并继续填充缓存。
关于弱引用的好处是,在我看来,这是实现内存中缓存的最佳方法之一,当我们需要保留数据不经常更改但经常在内存中访问且成本高昂时,通常会自行实现对于像JBoss缓存或EHCache这样的成熟的缓存实现而言,这实在太多了。 通常,我已经实现了缓存解决方案,还看到了类似于以下代码段的生产代码。
import java.util.HashMap;
import java.util.Map;
public class CacheTest {
private Map<String, Object> myAwesomeCache = new HashMap<String, Object>(100);
public Object getData(String id){
Object objToReturn = null;
if(myAwesomeCache.containsKey(id)){
objToReturn = myAwesomeCache.get(id);
}else{
// retrieve from the database and populate the in memory cache map
}
return objToReturn;
}
}
这只是一个非常基本的级别的实现,它可以使我们有时会使用Maps来构建内存缓存实现。 我们必须注意的事实是,尽管此实现没有本质上的错误,但是在您的应用程序内存不足的情况下,如果垃圾回收器可以将其从内存中删除以释放一些内存,这将是理想的选择其他需要它的过程。 但是,由于此映射是一个强大的参考,因此垃圾回收器无法将此参考标记为符合收集条件。 更好的解决方案是将缓存实现从HashMap更改为WeakHashMap 。
Javadoc指定了有关WeakHashMap的以下内容;
“基于哈希表的具有弱键的Map实现。 如果WeakHashMap中的条目不再是普通使用的键,它将自动被删除。 更准确地说,给定键的映射的存在不会阻止该键被垃圾收集器丢弃,即被终结化,终结和回收。 当一个键被丢弃时,它的条目会被有效地从映射中删除,因此此类的行为与其他Map实现有所不同。”
因此,回想起来,我相信只要您需要内存中的缓存实现,并且内存对您而言至关重要,那么使用WeakHashMap将会是有益的。
总结了我对参考资料包的发现,并邀请大家分享您在这方面的经验,对此深表感谢。
干杯
参考:在“ 我的旅程” IT博客中,从我们的JCG合作伙伴 Dinuka Arseculeratne 了解Java弱引用
翻译自: https://www.javacodegeeks.com/2012/01/understanding-java-weak-references.html