在Java中使用弱引用的代价
有没有人研究过创建和垃圾收集Java WeakReference对象所涉及的运行时成本? 多线程应用程序是否存在性能问题(如争用)?
编辑:显然实际的答案将是JVM的依赖,但一般的观察也是受欢迎的。
编辑2:如果有人已经做了一些性能基准测试,或者可以指出一些基准测试结果,那将是理想的。 (对不起,但赏金已过期...)
WeakReference对CMS垃圾回收器有负面影响。 就我从服务器的行为中可以看出,它影响并行备注阶段时间。 在此阶段,所有应用程序线程都会停止,因此这是非常不可取的事情。 所以你需要小心WeakReferences。
我实现了一次Java垃圾回收器,所以无论我能够完成什么,都可以实现(弱)下界。
在我的实现中,当垃圾收集期间访问每个弱引用时,会有少量不断的额外开销。
所以结果是:我不会担心它,这不是一个大问题,除非你使用了大量的弱引用。
最重要的是,成本与存在的弱引用的数量成正比,而不是整个堆的大小。
但是,这并不是说支持弱引用的垃圾收集器会比没有引用的垃圾收集器快。 这里推测的问题是,鉴于Java支持弱引用,使用它们的增量成本是多少?
矿是一个简单的“停止世界”标记/扫描垃圾收集器。 在垃圾收集期间,它会为每个对象确定该对象是否存在,并在对象头中设置一个LIVE
位。 然后它通过并释放所有非活的对象。
要处理弱引用,只需添加以下内容:
LIVE
位时忽略弱引用(即,它们不会导致引用对象上的LIVE
位被设置)。 LIVE
,并且是WeakReference
,那么检查它弱引用的对象,如果该对象不是LIVE
,请清除引用。 这种逻辑工作的小变化适用于软件和幻影参考。
如果你真的好奇,实现就在这里。
使用弱引用缓存可能会显着减慢您的应用程序,如果它正在按需重建,例如在getters中:
public Object getSomethingExpensiveToFind() {
if(cache.contains(EXPENSIVE_OBJ_KEY)) {
return cache.get(EXPENSIVE_OBJ_KEY);
}
Object sth = obtainSomethingExpensiveToFind(); // computationally expensive
cache.put(EXPENSIVE_OBJ_KEY, sth);
return sth;
}
想象这种情况:
1)应用程序内存不足
2)GC清除弱引用,因此缓存也被清除
3)应用程序继续,调用getSomethingExpensiveToFind()等许多方法并重建缓存
4)应用程序再次在内存中运行不足
5)GC清除磨损引用,清除缓存
6)app继续,调用getSomethingExpensiveToFind()等很多方法并重新生成缓存
7)等等...
我遇到了这样的问题 - 该应用程序经常被GC中断,并且它巧妙地击败了整个缓存点。
换句话说,如果管理不当,弱引用会降低应用程序的速度。
链接地址: http://www.djcxy.com/p/72769.html上一篇: Cost of using weak references in Java
下一篇: Is it possible to create a "weak reference" in javascript?