为什么Lua使用垃圾收集器而不是引用计数?

我听说并亲身经历过:Lua的垃圾回收器可能会导致游戏的帧数严重下降,因为它们的脚本部分增长。

我发现这与垃圾回收器有关,例如,每个创建的Vector()userdata对象暂时处于未使用状态,直到被垃圾回收。

我知道Python使用引用计数,这就是为什么它不需要像Lua的GC那样执行巨大的性能消耗步骤。

  • 为什么Lua不使用引用计数来处理垃圾?

原文链接 https://stackoverflow.com/questions/5010100

点赞
stackoverflow用户224346
stackoverflow用户224346

因为引用计数垃圾收集器容易泄漏对象。

简单的例子:一个双向链表。每个节点都指向下一个节点 - 并且被下一个节点指向。如果您仅取消对列表本身的引用并期望将其收集,那么您刚刚泄漏了整个列表 - 没有节点的引用计数为零,因此它们都将彼此保持活动状态。使用引用计数垃圾收集器,每当您有循环对象时,基本上需要将其视为未受管理的对象,并在完成后显式地处理它。

请注意,Python除了引用计数外还使用了适当的垃圾收集器。

python
2011-02-15 22:19:31
stackoverflow用户605059
stackoverflow用户605059

参考计数仅仅并不足够作为垃圾回收器正确工作的条件,因为它无法检测到循环引用。即使是 Python 也不仅仅使用参考计数。

假设对象 A 和 B 互相持有引用。即使你作为程序员不再持有任何一个对象的引用,参考计数仍然会提示对象 A 和 B 有指向它们的引用。

有许多不同的垃圾回收方案,某些方案在某些情况下运行得更好,某些方案在其他情况下则运行得更好。由语言设计者负责尝试选择最适合其语言的垃圾回收器。

2011-02-15 22:19:51
stackoverflow用户541686
stackoverflow用户541686

一般来说,由于可能存在循环引用的情况,引用计数并不是垃圾回收的完全替代品。您可能希望阅读 这个页面,以了解为什么垃圾回收被认为优于引用计数。

2011-02-15 22:19:54
stackoverflow用户596285
stackoverflow用户596285

虽然其他人已经解释了为什么需要垃圾回收器,但请记住,您可以在 Lua 中配置垃圾收集周期,使其更小、更少或按需进行。如果分配了大量内存并忙于绘制帧,则将阈值设置得非常大,以避免在游戏中断之前进行收集周期。

Lua 5.1 手册中的垃圾回收

2011-02-15 22:41:00
stackoverflow用户227513
stackoverflow用户227513

你所称基于的游戏使用的是哪个版本的 Lua?当《魔兽世界》从 Lua 5.0 转换到 5.1 时,所有垃圾回收引起的性能问题都得到了严重缓解。

在 Lua 5.0 的垃圾回收中,回收垃圾所需的时间(和任何同时运行的内容)与当前使用的内存量成比例,从而导致大量的工作要尽量减少 WoW 插件的内存使用。

在 Lua 5.1 的垃圾回收中,收集器改为渐进式,因此在收集垃圾时不会像以前那样锁定游戏。现在垃圾回收对性能的影响非常小,相比于大多数用户创建的插件中的效率极差的代码而言,垃圾回收仅是较大问题的一部分。

2011-02-15 22:42:22
stackoverflow用户513763
stackoverflow用户513763

你可能还感兴趣阅读关于优化的 Lua Gem,其中也有一个部分涉及垃圾回收。

2011-02-16 09:39:10
stackoverflow用户1599829
stackoverflow用户1599829

尝试查看一些 CPython 源代码。其中很大一部分的 C 代码是 Py_DECREFPy_INCREF。在 Lua 中,这种令人讨厌、冗长而易错的记账工作只需要消失即可。

如果需要的话,你可以写 C 的 Lua 模块去手动管理所有的重型私有分配。

2012-08-15 05:20:26
stackoverflow用户136829
stackoverflow用户136829

它是一种权衡。人们已经解释了一些语言(这与Lua无关)使用收集器的原因,但没有触及到缺点。

一些语言,特别是ObjC,仅使用引用计数。这样做的巨大优势是回收是确定性的-一旦你释放了最后一个引用,就保证对象会被立即释放。当你有内存限制时,这至关重要。使用Lua的分配器,如果内存限制需要预测回收,你必须添加方法来强制底层存储被立即释放,这违背了垃圾回收的初衷。

"WuHoUnited"错误地说你不能这样做——在iOS上使用ObjC和在C++中使用shared_ptr非常有效。你只需要了解你所处的环境,以避免循环或必要时打破循环。

2015-10-23 23:53:26