java 为什么我们在java中需要弱引用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11231565/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why do we need weak reference in java
提问by 18bytes
I understand that weak references are at the mercy of the garbage collector, and we cannot guarantee that the weak reference will exist. I could not see a need to have weak reference, but sure there should be a reason.
我知道弱引用受垃圾收集器的支配,我们不能保证弱引用会存在。我看不出需要弱引用,但肯定应该有一个原因。
- Why do we need weak reference in java?
- What are the practical (some) uses of weak reference in java? If you can share how you used in your project it will be great!
- 为什么我们在java中需要弱引用?
- java中弱引用的实际(某些)用途是什么?如果您能分享您在项目中的使用方式,那就太好了!
采纳答案by Voo
It's actually quite often a bad idea to use weak hashmaps. For one it's easy to get wrong, but even worse it's usually used to implement some kind of cache.
使用弱哈希图实际上通常是一个坏主意。一方面它很容易出错,但更糟糕的是它通常用于实现某种缓存。
What this does mean is the following: Your program runs fine with good performance for some time, under stress we allocate more and more memory (more requests = more memory pressure = probably more cache entries) which then leads to a GC.
这意味着以下内容:您的程序在一段时间内以良好的性能运行良好,在压力下我们分配越来越多的内存(更多请求 = 更多内存压力 = 可能更多缓存条目)然后导致 GC。
Now suddenly while your system is under high stress you not only get the GC, but also lose your whole cache, just when you'd need it the most. Not fun this problem, so you at least have to use a reasonably sized hard referenced LRU cache to mitigate that problem - you can still use the weakrefs then but only as an additional help.
现在突然间,当您的系统处于高压力下时,您不仅会获得 GC,而且还会在您最需要它的时候丢失整个缓存。这个问题不好玩,所以你至少必须使用一个合理大小的硬引用 LRU 缓存来缓解这个问题——你仍然可以使用弱引用,但只能作为额外的帮助。
I've seen more than one project hit by that "bug"..
我见过不止一个项目被那个“错误”击中。
回答by Louis Wasserman
The most "unambiguously sensible" use of weak references I've seen is Guava's Striped
, which does lock striping. Basically, if no threads currently hold a reference to a lock variable, then there's no reason to keep that lock around, is there? That lock might have been used in the past, but it's not necessary now.
我见过的最“明确合理”的弱引用使用是 Guava 的Striped
,它进行锁条带化。基本上,如果当前没有线程持有对锁变量的引用,那么就没有理由保留该锁,是吗?那个锁过去可能用过,但现在没有必要了。
If I had to give a rule for when you use which, I'd say that soft references are preferable when you mightuse something in the future, but could recompute it if you really needed it; weak references are especially preferable when you can be sure the value will never be needed after a reference goes out of memory. (For example, if you use the default reference equality for a particular equals(Object)
implementation for a map key type, and the object stops being referenced anywhere else, then you can be surethat entry will never be referenced again.
如果我必须为您何时使用 which 制定规则,我会说当您将来可能使用某些东西时,软引用更可取,但如果您真的需要它,可以重新计算它;当您可以确定在引用耗尽内存后永远不需要该值时,弱引用尤其可取。(例如,如果您equals(Object)
对映射键类型的特定实现使用默认引用相等,并且该对象停止在其他任何地方被引用,那么您可以确保该条目将永远不会被再次引用。
回答by pcalcao
The main reason for me to use weak references is indirectly, through a WeakHashMap.
我使用弱引用的主要原因是通过 WeakHashMap 间接使用。
You might want to store a collection of objects in a Map (as a cache or for any other reason), but don't want them to be in memory for as long as the Map exists, especially if the objects are relatively large.
您可能希望在 Map 中存储一组对象(作为缓存或出于任何其他原因),但不希望它们在 Map 存在时一直在内存中,尤其是在对象相对较大的情况下。
By using a WeakHashMap, you can make sure that the reference from the Map isn't the only thing keeping the object in memory, since it'll be garbage collected if no other references exist.
通过使用 WeakHashMap,您可以确保来自 Map 的引用不是将对象保留在内存中的唯一原因,因为如果不存在其他引用,它将被垃圾收集。
回答by Peter Lawrey
Say you need to keep some information as long as an object is referenced, but you don't know when it will go away, you can use a weak reference to keep track of the information.
假设只要一个对象被引用就需要保留一些信息,但是你不知道它什么时候会消失,你可以使用弱引用来跟踪信息。
回答by Subhrajyoti Majumder
Yes and it has good impact.
是的,它有很好的影响。
Example of "widget serial number" problem above, the easiest thing to do is use the built-in
WeakHashMap
class.WeakHashMap
works exactly likeHashMap
, except that the keys (not the values!) are referred to using weak references. If aWeakHashMap
key becomes garbage, its entry is removed automatically. This avoids the pitfalls I described and requires no changes other than the switch fromHashMap
to aWeakHashMap
. If you're following the standard convention of referring to your maps via theMap
interface, no other code needs to even be aware of the change.
上面的“小部件序列号”问题示例,最简单的方法是使用内置
WeakHashMap
类。WeakHashMap
工作方式与 完全一样HashMap
,不同之处在于键(不是值!)是使用弱引用来引用的。如果WeakHashMap
密钥变成垃圾,它的条目将被自动删除。这避免了我所描述的缺陷和需要比从开关之外,没有其他的改变HashMap
到一个WeakHashMap
。如果您遵循通过Map
接口引用您的地图的标准约定,则其他代码甚至不需要知道更改。
回答by Paolo Maresca
Weak Refernce Objects are needed to JVM platform to ensure means against the memory leaks.
JVM 平台需要弱引用对象来确保防止内存泄漏的手段。
As Java Developers should know, Java can leak, more than expected. This statement is particurarly true in those cases in which an Object is no longer used but some collection still refence strongly that instance: a very simple but recurrent example of memory leak, in fact that memory area will not be deallocated until the strong reference exists.
Java 开发人员应该知道,Java 可能会泄漏,超出预期。在不再使用 Object 但某些集合仍然强烈引用该实例的情况下,此语句尤其正确:这是一个非常简单但经常发生的内存泄漏示例,实际上在存在强引用之前不会释放内存区域。
In the above case, a Weak Reference Object in the collection assures that: without a strong references chain, but with only weak chains, the instance can be elcted as garbace collectable.
在上述情况下,集合中的弱引用对象确保:没有强引用链,但只有弱链,实例可以被选为垃圾收集。
In my opinion, all features provided by the Java Platform are useful to some extent: very skilled programmer can drive Java to be fast and reliable as C++ writing very high quality code.
在我看来,Java 平台提供的所有特性在某种程度上都是有用的:非常熟练的程序员可以驱动 Java 变得快速和可靠,就像 C++ 编写非常高质量的代码一样。
回答by Basil Bourque
Decoupling from pub-sub or event bus
与 pub-sub 或事件总线解耦
A WeakReference
is good when you want to let an object head for garbage-collection without having to gracefully remove itself from other objects holding an reference.
WeakReference
当您想让一个对象进行垃圾收集而不必从其他持有引用的对象中优雅地删除它自己时,A是很好的。
In scenarios such as publish-subscribeor an event bus, a collection of references to subscribing objects is held. Those references should be weak, so that the subscriber can conveniently go out of scope without bothering to unsubscribe. The subscriber can just “disappear” after all other places in the app have released their strong reference. At that point, there is no need for the subscription list or event bus to keep hanging on to the subscriber. The use of WeakReference
allows the object to continue on its way into oblivion.
在诸如发布-订阅或事件总线之类的场景中,持有对订阅对象的引用集合。这些引用应该是弱引用,以便订阅者可以方便地超出范围而不必费心取消订阅。订阅者可以在应用程序中的所有其他地方发布强引用后“消失”。那时,订阅列表或事件总线不需要一直挂在订阅者身上。的使用WeakReference
允许对象继续被遗忘。
The subscribing object may have been subscribed without its knowledge, submitted to the pub-sub or event bus by some other 3rd-party object. Coordinating a call to unsubscribe later in the life-cycle of the subscriber can be quite cumbersome. So letting the subscriber fade away without formally unsubscribing may greatly simplify your code, and can avoid difficult bugs if that unsubscribing coordination were to fail.
订阅对象可能在它不知情的情况下被订阅,由某个其他 3rd-party 对象提交到 pub-sub 或事件总线。在订阅者生命周期的后期协调取消订阅的调用可能非常麻烦。因此,让订阅者在没有正式取消订阅的情况下消失可能会大大简化您的代码,并且如果取消订阅协调失败,则可以避免困难的错误。
Here is an example of a thread-safe set of weak references, as seen in this Answerand this Answer.
this.subscribersSet =
Collections.synchronizedSet(
Collections.newSetFromMap(
new WeakHashMap <>()
)
);
Note that the entry in the set is not actually removed until aftergarbage-collection actually executes, as discussed in linked Answer above. While existing as a candidate for garbage-collection (no remaining strong references held anywhere), the item remains in the set.
请注意,在实际执行垃圾收集之后,集合中的条目实际上不会被删除,如上面链接的答案中所述。虽然作为垃圾收集的候选对象存在(任何地方都没有剩余的强引用),但该项目仍保留在集合中。
回答by jpe
It is required to make Java garbage collection deterministic. (From the slightly satirical point of view with some truth to it).
需要使Java 垃圾收集具有确定性。(从略微讽刺的角度来看,有些道理)。