C# 弱引用实际上是软引用吗?
基本区别在于,弱引用应该在每次 GC 运行时声明(保持低内存占用),而软引用应该保留在内存中,直到 GC 实际需要内存为止(它们试图延长生命周期,但可能随时失败,这对于例如缓存(尤其是相当昂贵的对象的缓存)很有用。
据我所知,关于弱引用如何影响 .NET 中对象的生命周期,还没有明确的说明。如果它们是真正的弱引用,它们根本不应该影响它,但这也会使它们对于我认为缓存的主要目的来说毫无用处(我错了吗?)。另一方面,如果他们表现得像软裁判,他们的名字就会有点误导。
就我个人而言,我认为它们的行为就像软引用,但这只是一种印象,并没有根据。
当然,实施细节也适用。我问的是与 .NET 弱引用相关的心态 - 它们是否能够延长生命周期,或者它们的行为是否像真正的弱引用?
(尽管有很多相关问题,但我还找不到这个具体问题的答案。)
The basic difference is that weak references are supposed to be claimed on each run of the GC (keep memory footprint low) while soft references ought to be kept in memory until the GC actually requires memory (they try to expand lifetime but may fail anytime, which is useful for e.g. caches especially of rather expensive objects).
To my knowledge, there is no clear statement as to how weak references influence the lifetime of an object in .NET. If they are true weak refs they should not influence it at all, but that would also render them pretty useless for their, I believe, main purpose of caching (am I wrong there?). On the other hand, if they act like soft refs, their name is a little misleading.
Personally, I imagine them to behave like soft references, but that is just an impression and not founded.
Implementation details apply, of course. I'm asking about the mentality associated with .NET's weak references - are they able to expand lifetime, or do they behave like true weak refs?
(Despite a number of related questions I could not find an answer to this specific issue yet.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
不。
你错了。弱引用的目的绝对不是您所说的缓存。这是一个常见的误解。
不,它们不会延长寿命。
考虑以下程序(F# 代码):
该堆分配一个立即适合垃圾回收的空数组。然后我们循环 10M 次分配更多无法访问的数组。请注意,这根本不会增加内存压力,因此没有动力收集弱引用引用的数组。然而程序打印“弱引用已死”,因为它仍然被收集。这是弱引用的行为。软引用将一直保留到实际需要其内存为止。
这是另一个测试程序(F# 代码):
它不断过滤掉无效的弱引用,并将新的弱引用添加到链表的前面,每次打印出列表的长度。在我的机器上,幸存的弱引用永远不会超过 1,000 个。它会循环上升然后下降到零,大概是因为在每个 gen0 收集中都会收集所有弱引用。再次强调,这是弱引用而不是软引用的行为。
请注意,这种行为(在第 0 代集合中积极收集弱引用对象)正是使弱引用成为缓存的糟糕选择的原因。如果您尝试在缓存中使用弱引用,那么您会发现缓存无缘无故地被大量刷新。
No.
You are wrong there. The purpose of weak references is absolutely not caching in the sense that you mean. That is a common misconception.
No, they do not expand lifetime.
Consider the following program (F# code):
This heap allocates an empty array that is immediately eligible for garbage collection. Then we loop 10M times allocating more unreachable arrays. Note that this does not increase memory pressure at all so there is no motivation to collect the array referred to by the weak reference. Yet the program prints "Weak reference is dead" because it was collected nevertheless. This is the behaviour of a weak reference. A soft reference would have been retained until its memory was actually needed.
Here is another test program (F# code):
This keeps filtering out dead weak references and prepending a fresh one onto the front of a linked list, printing out the length of the list each time. On my machine, this never exceeds 1,000 surviving weak references. It ramps up and then falls to zero in cycles, presumably because all of the weak references are collected at every gen0 collection. Again, this is the behaviour of a weak reference and not a soft reference.
Note that this behaviour (aggressive collection of weakly referenced objects at gen0 collections) is precisely what makes weak references a bad choice for caches. If you try to use weak references in your cache then you'll find your cache getting flushed a lot for no reason.
我没有看到任何信息表明它们会增加它们指向的对象的生命周期。我读到的有关 GC 用于确定可达性的算法的文章也没有以这种方式提及它们。所以我希望它们对对象的生命周期没有影响。
http://msdn.microsoft.com/en-us/library/83y4ak54.aspx
这里是一些无法访问的对象可以在垃圾回收中幸存下来的机制。
I have seen no information that indicates that they would increase the lifetime of the object they point to. And the articles I read about the algorithm the GC uses to determine reachability do not mention them in this way either. So I expect them to have no influence on the lifetime of the object.
http://msdn.microsoft.com/en-us/library/83y4ak54.aspx
There are a few mechanism by which an object that's unreachable can survive a garbage collection.
是
弱引用不会延长对象的生命周期,因此一旦所有强引用超出范围,就可以对其进行垃圾回收。它们对于保存初始化成本昂贵的大型对象很有用,但如果它们没有被积极使用,则应该可用于垃圾收集。
Yes
Weak references do not extend the lifespan of an object, thus allowing it to be garbage collected once all strong references have gone out of scope. They can be useful for holding on to large objects that are expensive to initialize but should be avaialble for garabage collection if they are not actively in use.