【问题标题】:How many objects are eligible for GC when line 18 //TODO [duplicate]第 18 行时有多少对象符合 GC 条件 //TODO [重复]
【发布时间】:2016-12-27 09:39:51
【问题描述】:

我有点困惑,在第 18 行时找出有多少对象符合 GC 条件。请解释一下

class B{}
class A{
    static B b1;
    B b2;
}
public class Test {
    public static void main(String[] args) {
        B b1=new B();
        B b2=new B();
        A a1=new A();
        A a2=new A();
        a1.b1=b1;
        a1.b2=b1;
        a2.b2=b2;
        a1=null;
        b1=null;
        b2=null;
        // TODO Auto-generated method stub
    }
}

第 19 行时有多少对象符合 GC 条件

【问题讨论】:

  • 取决于哪一行是第 19 行 ;)
  • 假设第 19 行是main 的最后一行(即右括号),所有对象都符合 GC 条件,因为这是程序的结尾。因为我不确切知道 JVM 加载了哪些类,所以我无法准确说出其中有多少。在a1 = null; 之后,只有a1 有资格进行gc。在b1 = null; 之后,b1 有资格获得 GC。 b2b2 = null; 之后没有资格获得 GC,因为它仍然可以通过 a2.b2 访问。
  • 参考我之前的评论:请注意,当我写“a1 获得 GC 资格”时,我实际上是指“对象,a1 在设置为 null 之前引用,有资格获得 GC”。很难谈论这个对象,因为只要它没有被垃圾收集,它就存在且无名。我希望预期的意思很清楚。
  • 在您告诉我们哪一行是第 19 行之前,这个问题是无法回答的。

标签: java object garbage-collection


【解决方案1】:

假设第 19 行是由TODO Auto-generated method stub 标记的行,那么在程序创建的对象中,第 19 行唯一符合 GC 条件的对象是变量引用的对象a1.

原来分配给a2的对象仍然被分配,所以不可用。

A.b1 中的静态值仍分配给最初分配给 b1 的对象,因此该对象不可用于 GC - 静态值在类的生命周期内有效,因此即使实例 a1 可能会被 GC'd通过它分配的静态实例仍然可以被引用。

因为实例 a2 仍然被赋值,所以实例字段 a2.b2 也不能用于 GC。该值保存了 B 的实例,该实例最初分配给 main 方法中的局部变量 b2。

在 main 方法中创建的四个对象中,程序最后一行实际可用于 GC 的唯一一个是最初分配给 a1 的对象。它的唯一引用已设置为 null,因此实例不再可访问。所有其他实例都可以通过局部变量 (a2)、静态引用 (A.b1) 或实例引用 (a2.b2) 访问。

【讨论】:

    【解决方案2】:

    绿色对象符合垃圾回收条件。

    只要一个对象符合垃圾回收条件,来自该对象的引用就不再重要了。

    但是,静态引用实际上并不需要对象存在(右边没有 : 的 A 表示静态引用 b1)。

    :A代表A类的一个对象

    :B代表B类的一个对象

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-31
      • 2017-12-26
      • 1970-01-01
      • 1970-01-01
      • 2023-03-27
      • 2016-01-20
      • 1970-01-01
      相关资源
      最近更新 更多