何时在Java中使用Weak和Phantom引用

When to use Weak and Phantom references in Java

我读了很多文章,但我不明白——在实践中,我需要在哪里使用弱引用和虚引用?软引用——据我所知,是缓存的好选择。但软弱和幻影,我不知道什么时候用。请提供我们需要使用的实际任务的示例。


您可以对缓存使用弱引用,就像您所说的软引用一样。

幻影参考有什么好处?我只知道它们有两个严重的情况:第一,它们允许您确切地确定从内存中删除对象的时间。事实上,它们是唯一确定这一点的方法。这通常没有那么有用,但在某些非常具体的情况下(如操作大型图像)可能会很有用:如果您确定应该对图像进行垃圾收集,则可以等到它实际存在时再尝试加载下一个图像,从而降低可怕的内存不足的可能性。

其次,phantomreferences避免了终结的一个基本问题:finalize()方法可以通过创建对对象的新的强引用来"复活"对象。你说呢?好吧,问题在于,现在必须确定重写finalize()的对象在至少两个单独的垃圾收集周期内是垃圾,以便进行收集。当第一个循环确定它是垃圾时,它就可以进行终结。由于对象在终结过程中"复活"的可能性(很小,但很不幸是真实的),垃圾收集器必须在实际删除对象之前再次运行。而且,由于可能没有及时完成,因此在对象等待完成时,可能会发生任意数量的垃圾收集周期。这可能意味着实际清理垃圾对象时会有严重的延迟,这也是为什么即使堆中的大部分是垃圾,也可以从内存错误中得到好处的原因。

有关详细信息,请参阅本页:http://weblogs.java.net/blog/2006/05/04/understanding-weak-references


基本上,当您想将一些额外的数据与源代码不受您控制的对象相关联时,您将使用弱引用。通过使用弱引用,可以将元对象的生命周期与主对象的生命周期结合起来。

幻影引用的主要用例是实现您自己的终结器线程,而不存在与默认机制相关联的危险,该机制强制引用终结代码所访问的假定不可访问的对象。

软引用主要用于缓存,但正如本文另一篇文章所述,软引用在实践中会产生灾难性的影响,从而破坏了缓存的关键点。一个主要的GC(将清除你的软引用的GC)通常不会发生,直到你的应用程序性能压力上升。这是您最需要缓存的时间,也是您最可能同时丢失缓存的时间–。


我认为这篇文章很好地回答了你的问题。

Java中的软引用和弱引用有什么区别?

基本上,软引用比弱引用略强。弱引用将在下一个GC循环中被丢弃,而软引用将保留在内存中,直到内存有压力,并且JVM希望尽可能多地回收。

您应该考虑到您的程序仍然有效的引用对您的程序有多重要。对于一些非常便宜的东西,我倾向于创建一个weakreference,但是如果它是一个来自db的值,那么您可能倾向于软引用,因为您不想重新运行查询,除非您真的需要。


这篇文章对这个问题有一个很好的答案。


在垃圾收集所有weakreference对象之前,不会收集SoftReference对象。

因此,将不太重要的对象放在weakreference对象中,并使用软引用对象来保存更重要的对象。

鉴于这些事实,在垃圾收集方面,您应该根据需要使用好的引用对象。首先收集weakreference,然后收集softreference,最后收集phantomreference。

文件上说:

  • 软引用用于实现内存敏感的缓存
  • 弱引用用于实现规范化映射,这些映射不会阻止其键(或值)被回收。

顺便说一下,在某些情况下,出于缓存的目的,最好使用weakreference而不是softreference,因为缓存在内存中可能很重,因此需要清理。

对于phantomreference,使用是不同的。它们是1〔0〕。

本文将详细介绍什么可以使用幻象引用。