我对此感到疑惑,因为那会使它们变得不那么有用。如果是这样,有没有办法让内存在主要GC上仅被“垃圾”弱引用?
答案 0 :(得分:7)
我不知道WeakReference
实际发生了什么。 javadoc没有具体说明清除/破坏它们的“时间尺度”。这将使你的问题得到答案(至少在理论上)“它依赖于实现”。实际上,JLS规范和javadocs甚至没有提到主要和次要集合。整个主题来自“实施细节”类别。
如果您确实需要GC敏感的引用,那么您可能应该使用SoftReference
。这描述如下:
“在虚拟机抛出OutOfMemoryError之前,保证已清除对软可访问对象的所有软引用。否则,不会对清除软引用的时间或其中的顺序进行约束将清除对不同对象的一组此类引用。但是,鼓励虚拟机实现偏向清除最近创建或最近使用的软引用。“
在其他地方,软参考被描述为比弱参考更强。这意味着它不太可能被打破;例如一个过度渴望的垃圾收集器。
但请注意,这甚至不涉及主要与次要垃圾收集。
答案 1 :(得分:5)
你为什么这么想?您的程序不应该关心主要GC次要和次要GC循环,事实上,所有JVM / GC配置中都不会存在这种区别。
只要没有对该对象的强引用, WeakReference
就可以收集。这可能包括次要的GC。
如果您希望对象在实际内存压力下保持一段时间,请尝试使用SoftReference。
答案 2 :(得分:3)
您可能会想到可能更接近您想要的SoftReferences。
次要集合将收集年轻空间中的任何对象。将在小型GC上收集对年轻空间中的对象的WeakReference。对终身空间中的对象的弱引用将被收集在终身收集中,例如完整的GC。顺便说一下,您可以只拥有终身空间的并发馆藏。
答案 3 :(得分:1)
这取决于WeakReference对象是否在Eden中 - 次要集合只会查看Eden中的对象。
答案 4 :(得分:0)
WeakReference
不会阻止对象的收集,因此如果对象属于年轻空间并且只能通过弱引用来访问它,那么它将被收集。
SoftReferences
(在HotSpot JVM中)作为弱引用或强引用,依赖于上次访问时间戳(引用时对get()
的最后一次调用的时间戳)。 sotf引用的“到期时间”计算为可用内存大小乘以-XX:SoftRefLRUPolicyMSPerMB=T
配置的系数(例如,可用内存减少,软引用短暂到期)。
通常,使用JVM引用进行缓存是个坏主意: - 它将临时对象提升到旧空间,打破弱世代假设 - 通过GC增加次要GC时间以特殊方式引用威胁
如果您需要具有驱逐策略的缓存,最好明确地实施它,并考虑在驱逐策略中影响存储数据的内存占用。
答案 5 :(得分:0)
布莱恩·戈茨(Brian Goetz)的一些见解(2006年的文章)似乎仍然存在于viguor中:
Soft References - > [穷人的缓存]和[垃圾收集器如何处理引用]段落中的有趣细节。