【问题标题】:Marked for garbage collection vs Eligible for garbage collection in java标记为垃圾收集与有资格在java中进行垃圾收集
【发布时间】:2018-06-10 22:52:01
【问题描述】:

我正在学习 Java 中垃圾收集的概念。据我所知,它说 GC 在后台定期运行并检查任何未引用或无法访问的对象。但是当内存有某种压力时,只有 GC 完成。 GC 也有标记阶段、重定位阶段等阶段。在下面的程序中,在第 1 行的末尾,对象 有资格 进行垃圾收集,因为不能保证 GC 将始终运行或它们在第 1 行之后立即标记进行 GC?

如果我的任何陈述有误,请纠正我。

public class ImmutableStrings
{
    public static void main(String[] args)
    {
        String one = "someString";
        String two = new String("someString");
        String three = "someString";
        one = two = three=null;
        System.out.println("testing "); // 1
        System.out.println("testing again");// 2
    }
}

在第 1 行,有多少对象被标记为垃圾回收? 据我说,2 个对象将符合 GC 并且没有标记。答案可能会有所不同

【问题讨论】:

  • 据我了解,内存中的对象已经符合垃圾收集的条件,但是,在垃圾收集“标记和清除”算法执行之前,它们仍会占用空间。我假设,GC 可能会在您将变量 1、2 和 3 标记为 null 后的那一刻运行,以便在第 1 行中,因此您可能对最后一个问题有多个答案。
  • 请注意,垃圾收集器的行为被有意定义得非常模糊,因此各种实现对其设置的限制很少。这也是 System.gc() 不一定做任何事情的原因。

标签: java garbage-collection


【解决方案1】:

在 GC真正运行之前,没有任何对象被标记为垃圾回收。并且标记由垃圾收集器制作,并且仅在 GC 运行时有效/有意义。

所以询问对象是否在代码中的特定点被标记是……没有意义的。

您可能试图区分不可访问的对象和 GC 实际收集的对象。但即使这样通常也是无法回答的,因为不同的 Java GC 在收集对象时的行为不同。


至于什么是符合条件的垃圾回收,计数取决于JVM / GC实现,以及你如何计算对象。例如:

  • 由显式new 创建的String 对象将(很可能)无法访问。

  • 与字符串文字对应的String 对象可能不会无法访问。 (除非 GC 足够聪明地意识到 main 方法不能再次使用它们......这是不可能的)

  • 但是……第一个 String 对象实际上里面有一个 char[]。

  • 而且...System.out.println("testing ") 调用可能会产生垃圾。

  • 而且 ... JVM 创建的任何数量的其他对象(在实例化 JVM、构建 args 数组、加载类等时)可能在那时无法访问。


简而言之,测验提出的问题过于模糊,无法得到绝对正确的答案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-16
    • 2010-12-13
    • 1970-01-01
    • 2016-03-26
    相关资源
    最近更新 更多