【问题标题】:Weak Reference and strong Reference弱引用和强引用
【发布时间】:2016-12-05 02:30:54
【问题描述】:

我有一个关于 Java 中的弱引用和强引用的非常基本的问题。

在一般 Java 编程中,我们通常不会创建对象的弱引用,我们会创建普通的强引用,但是当我们处理完该对象后,我们将 null 分配给该对象,其概念是,该对象将在下次被 GC 收集.

是不是我的理解有误?

看了一些文章后,看起来,对象被GC收集如果它是空的,或者只要它有弱引用,就没有在任何地方引用。我很困惑。

换句话说,就 Java GC 而言,这两个代码 sn-ps 有什么区别?

片段 1

Counter counter = new Counter(); // strong reference - line 1
WeakReference<Counter> weakCounter = new WeakReference<Counter>  (counter); //weak reference
counter = null;

片段 2

  Counter counter = new Counter(); // strong reference - line 1
  counter = null;

【问题讨论】:

  • 您要查找的词是reference
  • 您可能会在阅读我发布到另一个问题的答案时获得一些帮助。如果没有对它的强引用或软引用,WeakReference 的强度不足以强制对象在垃圾回收周期中存活。 stackoverflow.com/a/51891259/504133

标签: java collections garbage-collection weak-references


【解决方案1】:

在这两种情况下,counter 都可以进行垃圾回收。即使你使用SoftReference,它也会有GC的资格,但它只会被勉强收集。 (也就是说,SoftReference 鼓励 GC 将对象留在内存中,但仍然允许它被收集。)

只有硬引用会强制 GC 不理会对象。

通常,如果引用的寿命比您希望的对象长,您只需将 null 分配给引用。一旦硬引用变量超出范围,就不能再从实时代码中访问它,因此它的硬引用不会阻止 GC 收集对象。

还请注意,不能保证符合收集条件的对象何时真正被 GC 收集。它可能在下一个 GC 周期,也可能不在。这在很大程度上取决于 GC 的实现。唯一可以肯定的是,所有符合条件的对象都将在 VM 抛出 OutOfMemoryError 之前被收集。

【讨论】:

  • “硬引用”是否相同,即“强引用” - 只是通常的引用?
  • @Ekaterina - 是的,它们是一回事。例如,请参阅What is a hard reference in Java?
【解决方案2】:

不同的是,如果我没记错的话,

第一个代码片段在将对象计数器分配给weakCounter 之后将值null 分配给它。因此,weakCounter 仍然具有对旧计数器的引用,而对计数器的引用没有被更新。但是计数器仍然被编译器收集,即使weakCounter被分配给Counter的对象引用

在第二个代码示例中,计数器从分配给对象变为空值,让 java 知道“嘿,你可以把我收集到垃圾中!”

希望这是有道理的,如果我的某些事实有误,请随时告诉我我错在哪里:)

【讨论】:

  • 感谢您的回复……您的意思是一个是急切的过程(弱参考),另一个是请求过程(强参考)
【解决方案3】:

两者本质上是等价的,除了如果你在 GC 收集对象之前这样做,可能可以通过 WeakReference 引用对象。

WeakReference 的目的是让您可以将它隐藏在某个地方(例如,某种搜索索引),而不必担心如果您完成了对象并希望将任何“强”引用设为空(以便可以收集对象并重新使用空间)。如果您使用普通的强引用,则必须确保将其清除,否则该对象将永远挂起。

(Ted Hopp 提到的 SoftReferences 在机制上类似,只是 GC 只会在存储空间紧张的情况下收集引用的对象。这使得它们适用于缓存互联网页面之类的东西。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多