【问题标题】:weak reference to object containing a nested strong reference, and garbage collection对包含嵌套强引用的对象的弱引用和垃圾回收
【发布时间】:2010-04-06 12:20:02
【问题描述】:

假设我对具有普通(强)引擎引用的汽车有一个弱引用。不存在对汽车或发动机的其他参考。引擎可以被垃圾回收吗?

【问题讨论】:

    标签: java garbage-collection weak-references


    【解决方案1】:

    是的,这正是weak references 的工作原理。弱引用是您的对象对应用程序的根,即使对象可能有其他强引用,重要的是 root 引用,并且由于根引用是弱引用,因此对象将是垃圾收集的候选者。

    更多信息请查看WeakReference类文档:

    弱引用对象,不 防止他们的参照物 最终化,最终化,然后 回收。弱引用是最多的 常用于实现规范化 映射。

    假设垃圾收集器在某个时间点确定 一个对象是弱可达的。在 到时候它会原子地清除所有 对该对象的弱引用和所有 对任何其他的弱引用 弱可达对象 该对象可以通过 强软链 参考。同时它 将宣布所有以前的 弱可达对象 可最终确定的。同时或在 稍后它会将那些 新清除的弱引用是 使用参考队列注册。

    仅供参考,除了 WeakReference,Java 还提供了 Reference 的另外两个子类:SoftReferencePhantomReference

    【讨论】:

    • 我从来没有听说过弱引用这个表达,听起来它暗示了一些机制。如果我理解正确,问题是如果没有任何东西指汽车,引擎是否会被垃圾收集?
    • @James P.:WeakReference 是 Java 标准 API 中的一个类,它确实提供了一种特殊机制,即不会阻止对象符合垃圾回收条件的引用。
    【解决方案2】:

    Car 实例可以被垃圾回收,但不能保证它在下一个 GC 周期被垃圾回收,甚至不保证它会在全部。例如,

    • 在 GC 运行之前的某个时间,应用程序可以在 WeakReference 上调用 get 并将对 Car 的引用保存在(例如)某个可达对象的属性中。 Car 实例随后变得完全可访问,不再符合垃圾回收条件。

    • 如果 GC 在所描述的状态下以Car 运行,则 JVM 规范不保证在下一个 GC 周期中会检测到弱可达。例如,如果给定的 GC 周期只收集最新一代(并且 Car 已提升为老一代),则 GC 不会确定它是弱可达的。

    • 即使 GC 在 WeakReference 中中断对 Car 的引用,Car 实例也不会立即回收。相反,现在无法访问的Car 的回收可能会在稍后的 GC 周期中发生(在可能的最终确定之后)。

    【讨论】:

      【解决方案3】:

      这是一个演示弱引用的单元测试。请注意,System.gc() 不能保证对象会被垃圾回收,因此您不应依赖它。

      import junit.framework.TestCase;
      
      import java.lang.ref.WeakReference;
      
      public class WeakReferenceTest extends TestCase {
      
      
          class Car {
      
              Engine engine = new Engine();
      
          }
      
          class Engine {
      
          }
      
          public void testWeakReferences() {
              WeakReference<Car> carRef = new WeakReference<Car>(new Car());
              assertNotNull(carRef.get());
              System.gc();
              assertNull(carRef.get());
          }
      
      }
      

      【讨论】:

      • 符号 WeakReference 究竟是什么意思?
      • 对 System.gc() 的调用并不能保证最后一个断言将返回 true。
      • 它是泛型类WeakReference&lt;T&gt;的参数化,其中类型参数T是类Car
      • System.gc() 确实不能保证对象会被垃圾回收,你不应该依赖它。
      • Phil,Frederik,为什么不呢,System.gc() 可能不起作用或者你的论点是在哪里写的?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-11
      • 1970-01-01
      相关资源
      最近更新 更多