垃圾收集机制如何工作?

在非专业术语中,垃圾收集机制如何工作?

一个对象如何被识别为可用于垃圾收集?

另外,在GC算法中Reference Counting, Mark and Sweep, Copying, Train意味着什么?


当你使用垃圾收集语言时,你不会直接访问内存。 相反,您可以在数据上访问一些抽象。 被正确抽象出来的东西之一就是数据块内存的实际位置,以及指向其他数据块的指针。 当垃圾收集器运行时(偶尔会发生这种情况),它将检查是否仍持有对其分配给它的每个内存块的引用。 如果你不这样做,它将释放那个记忆。

垃圾收集器的不同类型之间的主要区别在于它们的效率以及它们可以处理什么样的分配方案的限制。

最简单的就是正确的参考计数。 当您创建对象的引用时,该对象上的内部计数器会递增,如果偶然引用或它不在范围内,则(之前)目标对象上的计数器递减。 当这个计数器达到零时,该对象不再被引用并且可以被释放。

引用计数垃圾收集器的问题是它们无法处理循环数据。 如果对象A具有对象B的引用,并且对对象A具有一些(直接或间接)引用,则即使链中没有任何对象在链之外被引用,它们也永远不会被释放(因此,根本无法访问该程序)。

另一方面,标记和扫描算法可以处理这个问题。 标记和扫描算法的工作原理是定期停止程序的执行,将程序分配的每个项目标记为不可访问。 然后程序运行程序所有的变量,并标记它们指向可达的地方。 如果这些分配中的任何一个包含对程序中其他数据的引用,则该数据同样被标记为可到达等等。

这是算法的标记部分。 此时,程序可以访问的所有内容,无论间接如何,都被标记为可访问,程序无法访问的所有内容都被标记为无法访问。 垃圾收集器现在可以安全地回收与标记为不可访问的对象关联的内存。

标记和扫描算法的问题在于效率不高 - 必须停止整个程序才能运行它,并且很多对象引用不会改变。

为了改善这一点,可以通过所谓的“分代垃圾收集”来扩展标记和扫描算法。 在这种模式下,已经在系统中存在一些垃圾收集数量的对象被提升到旧一代,而不是经常检查。

这可以提高效率,因为对象往往会年轻化(想象一个字符串在循环内部被改变,导致可能有几百个周期的寿命),或者活得很长(用于表示应用程序主窗口的对象,或者数据库连接的一个servlet)。

许多更详细的信息可以在维基百科上找到。

根据评论添加:

使用标记和扫描算法(以及除引用计数外的其他垃圾收集算法),垃圾收集不会在程序的上下文中运行,因为它必须能够访问程序无法直接访问的内容。 因此,说垃圾收集器在堆栈上运行是不正确的。


  • 引用计数 - 每个对象都有一个计数,当有人引用该对象时会递增计数,并且当某人释放引用时递减。 当引用计数变为零时,该对象被删除。 COM使用这种方法。
  • 标记和扫描 - 如果正在使用每个对象都有一个标记。 从对象图的根部开始(全局变量,堆栈上的本地等),每个引用的对象都会设置标志,依此类推。 最后,删除图中未引用的所有对象。
  • 在这个幻灯片中描述了CLR的垃圾收集器。 幻灯片15上的“根”是首先进入图表的对象的来源。 他们的成员字段等用于查找图中的其他对象。

    维基百科以更多更好的细节描述了其中的几种方法。


    垃圾收集只是简单地知道您的程序中是否有将来需要的变量,如果没有,则收集并删除它们。

    重点放在垃圾这个词上,在你的房子里被完全使用的东西扔在垃圾桶里,垃圾人通过把它拿起来把它拿走,把它拿走,给你的房子垃圾桶留出更多的空间。

    在GC常见问题解答中详细讨论了参考计数,标记和扫描,复印,培训等内容

    链接地址: http://www.djcxy.com/p/4657.html

    上一篇: How does the Garbage Collection mechanism work?

    下一篇: What is the difference between an annotated and unannotated tag?