如果存在两级软引用对象,GC将执行什么操作

时间:2012-05-14 23:29:01

标签: java garbage-collection soft-references

我知道在Java中我们有软引用的概念。如果:

1)软引用“sf”指对象A

2)在对象A中,它有一个强引用引用对象B

3)对象A& B不会在其他任何地方引用。

根据定义,对象A和对象B都“可以轻柔地到达”,对吗?

然后说我们现在用完了内存,GC开始了。有可能GC会回收对象B而不是对象A吗?

如果是这种情况,稍后如果我们想通过“sf”访问对象B,它将为null。 java如何避免这种情况发生?

我在java doc中没有看到任何解释。

3 个答案:

答案 0 :(得分:6)

  

然后说我们现在用完了内存,GC开始了。有可能GC会回收对象B而不是对象A吗?

没有。 GC不会破坏可到达对象中的强引用。 (当然,作为回收过程的一部分,它会破坏无法到达的对象中的引用。但是你无法观察到这种情况......因为要观察它,你需要仍然可以访问该对象。)

这是java.lang.ref包的javadoc中此语句的结果。

“最后,当一个对象无法访问,因此符合回收条件时,如果无法通过上述任何方式访问该对象。”

......其中“上述方式”包括强大,柔和,虚弱和虚幻的可达性。

这两个突出显示的词语意味着回收资格是处于无法到达状态的结果。由于其他州都没有提到填海资格,我们得出结论,不可达性是填海工程的先决条件。

这肯定与常识一致。如果(假设)允许GC在可到达对象中“清空”强引用,则应用程序在进入此状态后无法安全地处理对象。 (考虑这样一种情况,即引用的引用是在库类的实例中......)

答案 1 :(得分:2)

我认为简要介绍如何跟踪GCs基本上如何工作应该清理。

跟踪GC(Java和.NET中使用的那些都属于该类别)有一组所谓的root pointers,这些是全局变量(在java中表示类的静态变量)并且全部是堆栈框架中的变量。 GC遍历这些并标记所有活动的对象,即通过至少一个根指针的引用可到达。完成后,所有实时变量都已标记,其余的可以被垃圾收集。

现在可以用两种不同的方式处理软引用:a)我们遵循软引用并标记其中的所有对象或b)我们不这样做。究竟发生了什么是由给定的JVM实现的摆布,但在此之后已经确定没有其他区别。

因此有两种可能的情况:

  • GC遵循对A的软引用,在这种情况下,两个对象都不会被GC。
  • GC不遵循对A的软引用(并且没有硬引用)。 A是GCed,如果没有活动对象有参考,则B被GC。

答案 2 :(得分:1)

来自文档:

“如果一个对象不能很容易到达,但可以通过遍历一个软引用来访问它。”

“如果一个线程可以在不遍历任何引用对象的情况下到达某个对象,则可以强烈访问该对象”

我认为这很清楚。 B可以轻柔到达,因为它只能通过遍历软引用来访问。

Said Docs