垃圾收集机制如何工作? [关闭]

2024-01-14

用外行术语来说,垃圾收集机制是如何工作的?

如何识别对象可用于垃圾回收?

还有,做什么Reference Counting, Mark and Sweep, Copying, TrainGC 算法中的意思?


当您使用具有垃圾收集功能的语言时,您将无法直接访问内存。相反,您可以访问该数据之上的一些抽象。正确抽象的内容之一是数据块在内存中的实际位置,以及指向其他数据块的指针。当垃圾收集器运行时(这种情况偶尔会发生),它会检查您是否仍然保留对其为您分配的每个内存块的引用。如果你不这样做,它将释放该内存。

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

最简单的是正确的引用计数。当您创建对对象的引用时,该对象上的内部计数器就会递增,当您遇到该引用或者它不再在范围内时,(以前的)目标对象上的计数器就会递减。当该计数器达到零时,该对象根本不再被引用并且可以被释放。

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

另一方面,标记和清除算法can处理这个(事情。标记和清除算法的工作原理是定期停止程序的执行,将程序分配的每个项目标记为不可访问。然后,该程序会遍历该程序具有的所有变量,并将它们指向的内容标记为可达。如果这些分配中的任何一个包含对程序中其他数据的引用,则该数据同样被标记为可达等。

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

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

为了改进这一点,可以通过所谓的“分代垃圾收集”来扩展标记和清除算法。在这种模式下,系统中已经进行过一定次数垃圾收集的对象将被提升到老一代,而老一代不会经常被检查。

这提高了效率,因为对象往往会在很年轻的时候就死掉(想象一下循环内更改的字符串,导致生命周期可能有几百个周期)或寿命很长(用于表示应用程序主窗口的对象,或servlet 的数据库连接)。

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

根据评论添加:

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

垃圾收集机制如何工作? [关闭] 的相关文章

  • 运行“git gui”时如何跳过“松散对象”弹出窗口

    当我运行 git gui 时 我会看到一个弹出窗口 上面写着 This repository currently has approximately 1500 loose objects 然后它建议压缩数据库 我之前已经这样做过 它将松散对
  • 对象什么时候有资格进行垃圾收集?

    在下面的代码中 考虑到amethod已被调用 最初引用的对象在什么点 线上myObject 有资格进行垃圾收集吗 class Test private Object classObject public void amethod Objec
  • C++中delete和delete[]的区别[重复]

    这个问题在这里已经有答案了 可能的重复 C 中的删除与删除 运算符 https stackoverflow com questions 2425728 delete vs delete operators in c 我写了一个包含两个指针的
  • 弱变量中间为零

    弱变量什么时候变为零 weak var backgroundNode SKSpriteNode texture SKTexture image initialBackgroundImage backgroundNode position C
  • 为什么在方法中声明的对象在方法返回之前会受到垃圾回收?

    考虑在方法中声明的对象 public void foo final Object obj new Object A long run job that consumes tons of memory and triggers garbage
  • 循环内的局部变量会被垃圾收集吗?

    我想知道将循环内引用的任何变量放在循环外是否更有效 或者它们可以像函数内的变量一样被垃圾收集吗 var obj key val for var i 0 i lt 10 i console log obj or for var i 0 i l
  • Objective C (iphone) 关于发布的问题

    如果我创建一个视图 并将其添加为子视图并将其添加到数组中 是否必须释放它两次 UIView cat UIView alloc initWithFrame someFrame self view addSubview cat self ani
  • Java Runtime.getRuntime().freeMemory() 问题

    我搜索并看到了一些线程 但没有一个能够解决我遇到的具体问题 我正在尝试使用以下方式监视我的内存使用情况Runtime getRuntime freeMemory Runtime getRuntime maxMemory and Runtim
  • 为什么 std::allocator 在 C++17 中丢失成员类型/函数?

    一边看着std 分配器 http en cppreference com w cpp memory allocator 我看到成员 value type pointer const pointer reference const refer
  • C++ new int[0]——它会分配内存吗?

    一个简单的测试应用程序 cout lt lt new int 0 lt lt endl outputs 0x876c0b8 所以看起来确实有效 标准对此有何规定 分配 空内存块总是合法的吗 从5 3 4 7 当直接新声明符中的表达式的值为零
  • Objective C UIImagePNGRepresentation内存问题(使用ARC)

    我有一个基于 ARC 的应用程序 它从 Web 服务加载大约 2 000 个相当大 1 4MB 的 Base64 编码图像 它将 Base64 解码后的字符串转换为 png图像文件并将其保存到磁盘 这一切都是在一个循环中完成的 我不应该有任
  • 多维数组 (C++)

    我正在尝试将指针存储在数组中 我指向类对象的指针是 classType ClassObject 所以我知道我可以使用 new 运算符来分配它 如下所示 ClassObject new classType 100 我正在阅读一个带有标点符号的
  • 使用 using 来处理嵌套对象

    如果我有像这样的嵌套对象的代码 我是否需要使用嵌套的 using 语句来确保 SQLCommand 和 SQLConnection 对象都被正确处理 如下所示 或者如果实例化 SQLCommand 的代码位于外部使用语句 using var
  • 在 Windows Vista 和 Windows 7 上使用 HEAP_NO_SERIALIZE 的堆内存函数速度减慢约 100 倍的原因

    我正在尝试追踪 Windows Vista 和 Windows 7 中堆内存功能的巨大减慢 我没有在任何服务器版本上进行测试 这种情况在 Windows XP 上根本不会发生 只会在 Microsoft 较新的操作系统上发生 我最初在 Wi
  • 堆栈内存未释放

    我有以下循环 它从此处的实现中弹出我拥有的 C 并发队列 https juanchopanzacpp wordpress com 2013 02 26 concurrent queue c11 https juanchopanzacpp w
  • 需要澄清 NSAutoreleasePool

    每当我们打电话时autorelease方法 它的对象将是NSAutoreleasePool 当池耗尽时 它会向池中的所有对象发送释放消息 我的问题是 main函数中有一个NSAutoreleasePool 我想知道 当我们调用autorel
  • Xcode Instruments:模拟器中运行的 iPhone 应用程序的峰值 RAM?

    活动监视器 又名内存监视器 是 Xcode Instruments 中唯一可以测量在模拟器中运行的 iPhone 应用程序的总应用程序 RAM 使用情况的工具吗 只是显示瞬时有线 RAM 的那条线 与 iPhone 硬件相比 尤其是 OSX
  • 收集仍在范围内的对象 - GC.Collect

    我读过这篇文章 https devblogs microsoft com oldnewthing 20100810 00 p 13193 https devblogs microsoft com oldnewthing 20100810 0
  • 如何正确定义析构函数

    我对 C 以及一般的编程 比较陌生 所以如果问题没有立即完全清楚 请原谅我 我所拥有的是一个程序 其中创建了内部定义的类 让我们称之为 class1 的一定数量的对象 程序运行得很好 对象也做了它们应该做的事情 我当前试图解决的问题如下 这
  • C++ 对象用 new 创建,用 free() 销毁;这有多糟糕?

    我正在修改一个相对较大的 C 程序 不幸的是 并不总是清楚我之前的人使用的是 C 还是 C 语法 这是在一所大学的电气工程系 我们 EE 总是想用 C 来做所有事情 不幸的是 在这种情况下 人们实际上可以逃脱惩罚 但是 如果有人创建一个对象

随机推荐