有人能解释一下强引用、软引用、弱引用和虚引用之间的区别以及它们的用法吗?

30

我一直在尝试理解不同引用之间的差异,但是这个理论并没有给我任何可以将其可视化的想法。

请问有人能够简要地解释一下不同的引用吗?

最好再举出每种引用的例子。


3
相关但范围更窄:https://dev59.com/SnVC5IYBdhLWcg3wbQfA - Michael Myers
3个回答

21
另一篇与该主题相关的好文章:
Java引用对象或者说我如何学会不再担心OutOfMemoryError,带有很棒的图表。

http://www.kdgregory.com/images/java.refobj/object_life_cycle_with_refobj.gif

提取:

你可能会猜到,将三个新的可选状态添加到对象生命周期图中会变得一团糟。
虽然文档表明从强引用逐渐过渡到软引用、弱引用和虚引用,最终被回收,但实际上的过程取决于程序创建的引用对象。
如果你创建了一个 WeakReference 但没有创建 SoftReference,那么一个对象将直接从强可达到弱可达,然后到达终止状态和收集状态。对象的生命周期,以及引用对象

还要记住,并非所有对象都附加到引用对象上——事实上,很少有对象应该这样做
引用对象是一层间接关系:你通过引用对象来访问所引用的对象,显然你不想在整个代码中都有这种间接关系。
大多数程序实际上将使用引用对象来访问程序创建的相对较少的对象。

引用和所引用的对象

引用对象为你的程序代码和某些其他对象(称为所引用的对象)之间提供一层间接关系。
每个引用对象都是围绕其所引用的对象构建的,并提供一个 get() 方法来访问所引用的对象。一旦创建引用,就不能更改其所引用的对象。一旦所引用的对象被收集,get() 方法将返回 null。应用程序代码、软/弱引用和所引用的对象之间的关系

alt text


更多例子:Java编程:引用包

alt文本 http://www.pabrantes.net/blog/space/start/2007-09-16/1/referenceTypes.png

  • 情况1:这是常规情况,其中对象被认为是强可达的。

  • 情况2:有两条路径通往对象,因此选择最强的路径,即具有强引用的路径,因此对象是强可达的。

  • 情况3:再次有两条路径到达对象,最强的路径是弱引用(另一条路径是虚引用),因此对象被认为是弱可达的。

  • 情况4:只有一条路径,并且最弱的链接是弱引用,因此对象是弱可达的。

  • 情况5:只有一条路径,最弱的链接是虚引用,因此对象是虚可达的。

  • 情况6:现在有两条路径,最强的路径是具有软引用的路径,因此对象现在被认为是软可达的。


1
+1,不仅提供URL :) - Andreas Dolk
之后,可以尝试不同的垃圾回收模式进行测试:http://www.artima.com/insidejvm/ed2/gcP.html - VonC
Java编程:References' Package解释了我想要的内容。现在我已经清楚地了解了什么是引用。 - Jegan Kunniya
很高兴你喜欢这篇文章 :-) 在我的404报告中看到了这些链接。 - kdgregory
@kdgregory:感谢您的更新 :) 确实是一篇很棒的文章。 - VonC
那篇文章真是太棒了。谢谢! - Eugene

7

1
链接已损坏。这就是为什么我们应该引用页面内容而不是提供链接的原因。 - Ravi

3

有一个非常简单的规则:

  • 强引用对象是像Object a = new Object()这样的标准代码块。只要引用(如上面的a)是“可达”的,那么引用对象就不是垃圾。因此,任何没有可达强引用的东西都可以被视为垃圾

然后我们看看非强引用类型:

  • 弱引用对象一旦成为GC的候选对象(并且WeakReference已清除),就可能会被JVM收集。对a的弱引用看起来像new WeakReference<Object>(a)。如果您需要缓存,其中数据仅在键在其他地方存在为强可达时才需要它(例如HttpSessions),则弱引用非常有用。
  • 软引用对象可能会在JVM中挂起,直到绝对需要回收内存。如果必要,可以使用软引用来缓存长期存在但可以收集的值。

我对幽灵引用从来不太确定!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接