我读了很多文章,但我不明白——在实践中,哪里需要使用弱引用和幻影引用?据我所知,软引用是缓存的一个不错的选择。但是虚弱和虚幻,我不知道什么时候该用。请提供我们需要使用的实际任务的示例。
您可以使用弱引用进行缓存,就像您所说的软引用一样。
PhantomReferences有什么好处?我只知道它们有两种严重的情况:首先,它们允许您准确地确定对象何时从内存中删除。事实上,它们是确定这一点的唯一途径。这通常没有那么有用,但在某些非常特殊的情况下可能会派上用场,比如处理大图像:如果你确信一个图像应该被垃圾收集,你可以等到它真正被垃圾收集后再尝试加载下一个图像,从而降低可怕的OutOfMemoryError的可能性。
其次,PhantomReferences避免了终结的一个根本问题:finalize()方法可以通过创建对对象的新的强引用来"复活"对象。你说呢?问题是,重写finalize()的对象现在必须在至少两个独立的垃圾收集周期中被确定为垃圾,才能被收集。当第一个循环确定它是垃圾时,它就有资格进行终结。由于对象在完成过程中被"复活"的可能性很小,但不幸的是,在真正删除对象之前,垃圾收集器必须再次运行。由于终结可能没有及时发生,因此在对象等待终结时可能发生了任意数量的垃圾收集循环。这可能意味着在实际清理垃圾对象时会出现严重延迟,这就是为什么即使大多数堆都是垃圾,也可以获得OutOfMemoryErrors的原因。
有关更多详细信息,请参阅本页:http://weblogs.java.net/blog/2006/05/04/understanding-weak-references
基本上,当您想将一些额外的数据与源代码不在您控制范围内的对象关联时,您将使用弱引用。通过使用弱ref,您可以将元对象的生命周期与主对象的生命期相耦合。
phantom refs的主要用例是在没有与默认机制相关的危险的情况下实现自己的终结器线程,默认机制被迫使对假定不可访问的对象的引用可由终结代码访问。
软引用主要用于缓存,但正如在这里的另一篇文章中所说,它们在实践中可能会产生相当灾难性的影响,破坏缓存的重要性。在应用程序性能压力上升之前,通常不会发生重大GC(清除软引用的GC)。这是您最需要缓存的时候,也是您最有可能丢失缓存的时候–一次完成。
我认为这篇文章很好地回答了你的问题。
Java中的软引用和弱引用之间有什么区别?
基本上,软引用比弱引用稍微强一点。弱引用将在下一个GC周期中被丢弃,而软引用将保留在内存中,直到内存出现压力,JVM希望尽可能多地回收。
你应该考虑一下你的参考资料仍然有效对你的程序有多重要。对于重新创建引用非常便宜的东西,我会倾向于WeakReference,但如果它是来自DB的值,你可能会倾向于软引用,因为除非你真的需要,否则你宁愿不重新运行查询。
SoftReference对象直到所有WeakReference对象都被垃圾收集后才会被收集。
因此,将不太重要的对象放在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.
这篇文章详细阐述了PhantomReference的用途。