我阅读了很多文章,但我不明白 - 在实践中我需要在哪里使用Weak和Phantom参考?软错误引用 - 正如我所理解的那样,是缓存的不错选择。但弱和幻影,我不知道何时使用。请提供我们需要使用它们的实际任务示例。
答案 0 :(得分:8)
您可以使用弱引用进行缓存,就像您所说的软引用一样。
PhantomReferences有什么用?我只知道它们有两个严重的情况:首先,它们允许您确定何时从内存中删除对象。事实上,它们是确定这一点的唯一方法。这通常不是很有用,但在某些非常特殊的情况下可能会派上用场,例如操作大图像:如果你确定图像应该被垃圾收集,你可以等到它实际上是在尝试加载下一个图像之前,因此不太可能使可怕的OutOfMemoryError。
其次,PhantomReferences避免了最终化的基本问题:finalize()方法可以通过创建对它们的新的强引用来“复活”对象。那么,你说什么?好吧,问题是现在必须确定覆盖finalize()的对象至少在两个单独的垃圾收集周期中是垃圾才能被收集。当第一个周期确定它是垃圾时,它有资格完成。由于在完成期间对象被“复活”的(微小但不幸的是真实的)可能性,垃圾收集器必须在实际移除对象之前再次运行。并且由于最终确定可能不会及时发生,因此在对象等待最终确定时可能会发生任意数量的垃圾收集周期。这可能意味着实际清理垃圾对象的严重延迟,这就是为什么即使大部分堆都是垃圾也可以获得OutOfMemoryErrors。
有关详细信息,请参阅此页面: http://weblogs.java.net/blog/2006/05/04/understanding-weak-references
答案 1 :(得分:5)
基本上,当您想要将一些其他数据与源代码不受您控制的对象相关联时,您将使用弱引用。通过使用弱引用,您可以将元对象的生命周期耦合到主对象的生命周期。
幻像引用的主要用例是实现自己的终结器线程,而没有与默认机制相关的危险,默认机制被迫对最终化代码可访问的所谓无法访问的对象进行引用。
软补率主要用于缓存,但正如在另一篇文章中所述,它们在实践中可能会产生相当大的灾难性影响,从而破坏了缓存的重点。一个主要的GC(将清除你的Soft refs的那个)通常不会发生,直到你的应用程序的性能压力上升。这是您最需要缓存的时间,以及您最有可能丢失缓存的时间 - 一次性完成。
答案 2 :(得分:3)
我认为这篇文章很好地回答了你的问题。
What is the difference between a soft reference and a weak reference in Java?
基本上,软参考比弱参考略强。弱引用将在下一个GC周期中被丢弃,而软引用将保留在内存中,直到存在内存压力并且JVM想要尽可能多地回收。
您应该考虑您的程序对您的参考仍然有效的重要性。对于重新创建引用非常便宜的东西,我会倾向于WeakReference,但如果它是来自DB的值,您可能倾向于软引用,因为除非您确实需要,否则不要重新运行查询。 / p>
答案 3 :(得分:2)
这个article对这个问题有很好的答案。
答案 4 :(得分:0)
在对所有WeakReference对象进行垃圾回收之前,不会收集SoftReference对象。
因此,在WeakReference对象中放置不太重要的对象,并使用SoftReference对象来保存更重要的对象。
鉴于这些事实,你应该根据垃圾收集的需要使用好的Reference对象。首先收集WeakReference,然后收集SoftReference,最后收集PhantomReferences。
顺便说一下,在某些情况下,出于缓存目的,使用WeakReference而不是SoftReference是个好主意,因为缓存在内存中很重,因此需要清理。
对于PhantomReference,使用方法不同。他们are for scheduling pre-mortem cleanup actions in a more flexible way than is possible with the Java finalization mechanism.
This article详细说明了PhantomReference的用途。