Lua 使用具有相同名称的多个局部变量时的垃圾回收

Lua 使用具有相同名称的多个局部变量时的垃圾回收,lua,Lua,考虑以下代码: local v = "hello" a = function() print(v) end local v = "world" b = function() print(v) end a() b() 输出为: hello world 通常,我希望hello一旦被world覆盖,就会被标记为垃圾收集。但是,由于a引用了hello我假设hello只要a仍然存在,就不会被垃圾收集。这样做 a = nil 将a和hello标记为垃圾收集。是这

考虑以下代码:

local v = "hello"
a = function() print(v) end
local v = "world"
b = function() print(v) end
a()
b()
输出为:

hello
world
通常,我希望
hello
一旦被
world
覆盖,就会被标记为垃圾收集。但是,由于
a
引用了
hello
我假设
hello
只要
a
仍然存在,就不会被垃圾收集。这样做

a = nil
a
hello
标记为垃圾收集。是这样吗

通常,我希望
hello
被标记为垃圾收集 一旦它被
world
覆盖

hello不会被世界覆盖。它不再被
v

a=nil
将标记垃圾收集的函数值,因为它删除了对它的唯一引用


函数值消失后,再也没有任何东西指向“hello”,因此它也将被收集。

两个同名的局部变量在技术上是两个不同的变量。变量作用域持续到代码块结束。最大的问题是垃圾收集器是否可以检测隐藏的变量。如果不能,则第一个
v
将保留在内存中,直到块结束

在下面的代码中,我使用表而不是字符串。由于字符串文字嵌入在字节码中,因此使用字符串会使查看内存使用情况变得更加困难

local function showMemory()
  -- Do a full GC cycle to get a clean memory reading.
  collectgarbage()
  -- Show memory usage in bytes.
  print(collectgarbage'count' * 1024)
end

showMemory()
local v = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
showMemory()
local v = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
showMemory()
输出:

24003.0
24291.0
24507.0
24019.0
24307.0
24091.0
24307.0
第一个
v
增加了288字节的内存使用量。第二个
v
添加216字节

现在让我们看看当我们使用
do
--
end
强制第一个
v
超出范围时会发生什么:

local function showMemory()
  collectgarbage()
  print(collectgarbage'count' * 1024)
end

showMemory()
do
  local v = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
  showMemory()
end
showMemory()
local v = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
showMemory()
输出:

24003.0
24291.0
24507.0
24019.0
24307.0
24091.0
24307.0
在这里,我们看到在每次
v
声明之后,内存使用量是完全相同的。显然,两个
v
s是否在同一范围内有很大区别


由此,我得出结论,声明局部变量不会导致以前同名的变量被垃圾收集。

您是在询问使用了多少内存,还是只关心在程序中的给定点可以以某种方式访问哪些值?只关心内存消耗。我的示例中的字符串只是用来说明问题的占位符。事实上,这些都是需要大量内存的大桌子。谢谢,我想你是对的。在我的原始代码中,当设置
a=nil
时,第一个
v
可能甚至没有被垃圾收集,因为它仍然在作用域中,即使它不再在该作用域中可访问,因为对
v
的所有进一步引用都将引用第二个
v
。因此,如果垃圾收集器很聪明,它应该能够检测到第一个
v
可以被收集,因为它不再可访问。然而,从你的观察来看,它似乎没有能力做到这一点。。。