什么时候应该使用弱引用?

发布于 2024-08-09 20:42:49 字数 201 浏览 3 评论 0原文

我最近遇到了一段带有 WeakReferences 的 Java 代码 - 尽管在引入它们时我就遇到过它们,但我从未见过它们的部署。这是应该经常使用的东西还是只有在遇到内存问题时才使用?如果是后者,它们是否可以轻松改造或者代码是否需要认真重构?一般的 Java(或 C#)程序员通常会忽略它们吗?

编辑过度热衷使用WR会造成任何损害吗?

I recently came across a piece of Java code with WeakReferences - I had never seen them deployed although I'd come across them when they were introduced. Is this something that should be routinely used or only when one runs into memory problems? If the latter, can they be easily retrofitted or does the code need serious refactoring? Can the average Java (or C#) programmer generally ignore them?

EDIT Can any damage be done by over-enthusiastic use of WRs?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

趴在窗边数星星i 2024-08-16 20:42:49

弱引用都是关于垃圾收集的。 标准对象在对它的所有引用都被切断之前不会“消失”,这意味着在垃圾收集将其视为垃圾之前,必须删除各种对象对其的所有引用。

使用弱引用仅仅因为您的对象被其他对象引用并不一定意味着它不是垃圾。它仍然可以被 GC 拾取并从内存中删除。

举个例子:如果我的应用程序中有一堆 Foo 对象,我可能想使用 Set 来保存我周围所有 Foo 的中央记录。但是,当我的应用程序的其他部分通过删除对 Foo 对象的所有引用来删除该对象时,我不希望 Set 保留对该对象的剩余引用以防止其被垃圾收集!真的,我只是想让它从我的集合中消失。这时您可以使用弱集(Java 有一个 WeakHashMap)之类的东西,它使用对其成员的弱引用而不是“强”引用。

如果你的对象没有在你想要的时候被垃圾收集,那么你在记账中犯了一个错误,某些东西仍然保留着你忘记删除的引用。使用弱引用可以减轻这种簿记的痛苦,因为您不必担心它们使对象保持“活动”状态并且不会被垃圾收集,但您必须使用他们。

Weak references are all about garbage collection. A standard object will not "disappear" until all references to it are severed, this means all the references your various objects have to it have to be removed before garbage collection will consider it garbage.

With a weak reference just because your object is referenced by other objects doesn't necessarily mean it's not garbage. It can still get picked up by GC and get removed from memory.

An example: If I have a bunch of Foo objects in my application I might want to use a Set to keep a central record of all the Foo's I have around. But, when other parts of my application remove a Foo object by deleting all references to it, I don't want the remaining reference my Set holds to that object to keep it from being garbage collected! Really I just want it to disappear from my set. This is where you'd use something like a Weak Set (Java has a WeakHashMap) instead, which uses weak references to its members instead of "strong" references.

If your objects aren't being garbage collected when you want them to then you've made an error in your book keeping, something's still holding a reference that you forgot to remove. Using weak references can ease the pain of such book keeping, since you don't have to worry about them keeping an object "alive" and un-garbage-collected, but you don't have to use them.

呆萌少年 2024-08-16 20:42:49

每当您想要引用某个对象而不需要自己保持该对象处于活动状态时,就可以使用它们。这对于许多类似缓存的功能来说都是如此,而且在事件处理中也发挥着重要作用,其中订阅者不应通过订阅事件来保持活动状态。

一个小例子:刷新一些数据的计时器事件。任意数量的对象都可以订阅计时器以获得通知,但它们订阅计时器的事实不应该让它们保持活动状态。所以计时器应该对对象有弱引用。

You use them whenever you want to have a reference to an object without keeping the object alive yourself. This is true for many caching-like features, but also play an important role in event handling, where a subscriber shall not be kept alive by being subscribed to an event.

A small example: A timer event which refreshes some data. Any number of objects can subscribe on the timer in order to get notified, but the bare fact that they subscribed on the timer should not keep them alive. So the timer should have weak references to the objects.

夏末 2024-08-16 20:42:49

是否会造成任何损坏
过度热衷于使用WR?

是的,可以。

一个问题是弱引用会使您的代码更加复杂并且可能容易出错。任何使用弱引用的代码都需要处理每次使用引用时被破坏的可能性。如果过度使用弱引用,您最终会编写大量额外的代码。 (您可以通过将每个弱引用隐藏在负责检查的方法后面来减轻这种情况,并根据需要重新创建丢弃的对象。但这可能不一定那么简单;例如,如果重新创建过程涉及网络访问,您需要应对重新创建失败的可能性。)

第二个问题是使用弱引用会产生运行时开销。明显的成本是创建弱引用并对其调用 get 的成本。一个不太明显的成本是每次 GC 运行时都需要完成大量的额外工作。

最后一个问题是,如果您对应用程序将来很可能需要的内容使用弱引用,则可能会产生重复重新创建它的成本。如果此成本很高(就 CPU 时间、IO 带宽、网络流量等而言),您的应用程序可能会表现得很差。给 JVM 更多内存并且根本不使用弱引用可能会更好。

当然,这并不意味着您应该完全避免使用弱引用。只是你需要仔细考虑一下。也许您应该首先在应用程序上运行内存分析器来找出内存使用问题的根源。

Can any damage be done by
over-enthusiastic use of WRs?

Yes it can.

One concern is that weak references make your code more complicated and potentially error prone. Any code that uses a weak reference needs to deal with the possibility that the reference has been broken each time it uses it. If you over-use weak references you end up writing lots of extra code. (You can mitigate this by hiding each weak reference behind a method that takes care of the checking, and re-creates the discarded object on demand. But this may not necessarily be as simple as that; e.g. if the re-creation process involves network access, you need to cope with the possibility of re-creation failure.)

A second concern is that there are runtime overheads with using weak references. The obvious costs are those of creating weak references and calling get on them. A less obvious cost is that significant extra work needs to be done each time the GC runs.

A final concern is that if you use a weak references for something that your application is highly likely to need in the future, you may incur the cost of repeatedly recreating it. If this cost is high (in terms of CPU time, IO bandwidth, network traffic, whatever) your application may perform badly as a result. You may be better off giving the JVM more memory and not using weak references at all.

Off course, this does not mean you should avoid using weak references entirely. Just that you need to think carefully. And probably you should first run a memory profiler on your application to figure out where your memory usage problems stem from.

泡沫很甜 2024-08-16 20:42:49

在考虑使用 Wea​​kReference 时要问的一个好问题是,如果在对象不存在强引用的情况下弱引用失效,人们会有什么感觉。如果这会降低 WeakReference 的用处,那么 WeakReference 可能不是最好的选择。如果这将是对来自垃圾收集的非确定性失效的改进,那么 WeakReference 可能是正确的选择。

A good question to ask when considering use of a WeakReference is how one would feel if the weak reference were invalidated the instant no strong references existed to the object. If that would make the WeakReference less useful, then a WeakReference is probably not the best thing to use. If that would be an improvement over the non-deterministic invalidation that comes from garbage-collection, then a WeakReference is probably the right choice.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文