【问题标题】:Garbage Collection in JavaJava中的垃圾收集
【发布时间】:2011-02-25 22:25:08
【问题描述】:

在我正在修改的幻灯片上写着以下内容:

可以通过维护对每个对象的引用数的计数,或通过从根跟踪引用链来识别活动对象。

引用计数很昂贵——每次引用更改时都需要采取行动,而且它不会发现循环结构,但它可以逐步回收空间。

跟踪涉及仅在您需要回收空间时识别活动对象 - 将成本从一般访问转移到 GC 运行时,通常仅在您内存不足时。

我了解为什么引用计数昂贵的原理,但不明白什么 “没有发现周期性结构,但它可以逐步回收空间。”方法。有谁能帮帮我吗?

谢谢

【问题讨论】:

    标签: java algorithm memory garbage-collection reference-counting


    【解决方案1】:

    “没有发现周期性结构”

    假设我有一个对象AA 需要另一个名为 B 的对象来完成它的工作。但是B 需要另一个名为C 的对象来完成它的工作。但是C 出于某种原因需要指向A 的指针。所以依赖图看起来像:

    A -> B -> C -> A
    

    对象的引用计数应该是指向它的箭头数。在这个例子中,每个对象都有一个引用计数。

    假设我们的主程序在执行过程中创建了一个这样的结构,并且主程序有一个指向A 的指针,使A 的计数等于2。当这个结构超出范围时会发生什么? A 的引用计数减一。

    但请注意!现在 ABC 的引用计数均为 1,即使 它们无法从主程序访问。所以这是内存泄漏。维基百科有details 告诉你如何解决这个问题。

    "它可以逐步回收空间"

    大多数垃圾收集器都有一个收集周期,在此期间它们会暂停执行并释放不再使用的对象。在标记和扫描系统中,这是扫描步骤。不利的一面是,在两次扫描之间的时间段内,内存不断增长。对象可能在创建后几乎立即停止使用,但在下一次扫描之前永远不会被回收。

    在引用计数系统中,对象的引用计数一达到零就会被释放。没有大的停顿或任何大的扫描步骤,不再使用的对象不会只是坐在那里等待收集,它们会立即被释放。因此,该集合是增量的,因为它增量地收集任何不再使用的对象,而不是批量收集自上次收集以来不再使用的所有对象。

    当然,这种渐进主义可能有其自身的缺陷,即进行批量 GC 可能比进行大量小 GC 成本更低,但这取决于具体的实现。

    【讨论】:

      【解决方案2】:

      引用计数没有发现循环结构...

      假设您有两个对象 O1 和 O2。它们相互引用:O1 -> O2 和 O2 -> O1,并且没有其他对象引用它们。它们的引用计数都为 1(一个引用者)。

      如果 O1 或 O2 都无法从 GC 根访问,则可以安全地对它们进行垃圾回收。这不是通过计数引用来检测的,因为它们的引用计数都 > 0。

      0 引用是一个充分但非必要的要求,对象有资格进行垃圾回收。

      ...但它可以逐步回收空间。

      增量部分是指您可以快速垃圾收集一些 0 引用的对象,被中断并在另一个时间继续而不会出现问题。

      如果跟踪算法被中断,它将需要在下一次安排时从头开始。 (引用树可能从一开始就发生了变化!)

      【讨论】:

      • 我们能否得出结论,0 个引用或无法访问 是必要的要求?
      • 无法访问是必要的要求。 0 个引用只是无法访问的子集。
      • @sev,是的,应该是正确的。 @Tim,它可以是 GC 根集的一部分,那么它可能有 0 个引用,但仍然可以访问。
      【解决方案3】:

      如果引用计数达到 0,则可以释放对象进行垃圾收集。

      对于循环引用,这永远不会发生,因为循环中的每个对象都保持对另一个对象的引用,因此它们都至少为 1。

      为此,需要一些图论来检测不再附加到任何东西的引用,例如堆海中的小岛。为了将它们保存在内存中,它们必须对某个静态变量有一些“附加”。

      这就是追踪的作用。它确定堆的哪些部分是孤岛并且可以被释放,哪些仍然连接到大陆,即静态变量smewhere。

      【讨论】:

        【解决方案4】:

        假设您有三个对象(A、B、C):A 对 B 有引用,B 对 C 有引用,C 对 A 有引用。但没有其他对象对其中一个有任何引用。是一个独立的循环结构。使用传统的引用计数会阻止垃圾收集器移除循环,因为每个对象仍然被引用。但只要没有人对这三个中的一个有参考,他们就可以/应该被删除。我猜增量回收空间意味着在查找未引用实例、无循环等时引用计数的工作方式。

        【讨论】:

          【解决方案5】:
          1. 简单的引用计数无法解决A引用B和B引用A的情况。在这种情况下,A和B的引用计数都为1,即使没有其他引用也不会被收集。
          2. 当某个对象的引用计数器变为 0 时,引用计数可以立即回收空间。无需等待 GC 周期,扫描其他对象等。因此,从某种意义上说,它以递增的方式工作,因为它从对象中逐一回收空间一个。

          【讨论】:

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