Lua元表对象无法从内存中清除?
我使用了一个专有的平台,在屏幕上实时报告内存使用情况。我决定使用我在http://lua-users.org/wiki/SimpleLuaClasses找到的Class.lua。
然而,我注意到使用一个简单的Account类创建的对象在清除内存时存在问题。具体来说,我开始使用146k的内存,创建1000个只包含一个整数实例变量的类对象,并将每个对象存储到一个表中。现在使用的内存为300k。
然后我退出,迭代表格并将表中的每个元素设置为nil。但不会回收146k,通常在此之后我会使用210k或类似的内存。如果在同一会话中再次运行加载顺序,则不会超过300k,因此这不是内存泄漏。
我尝试在表中创建1000个整数并将其设置为nil,这确实使我回收了146k。
此外,我尝试了一个更简单的类文件(Account2.lua),它不依赖于Class.lua。这仍会导致内存碎片,但不像使用Class.lua那样严重。
有人能解释这是怎么回事吗?我如何清除这些对象并恢复内存?
这里是代码
--------Class.lua------
-- class.lua
-- 兼容Lua 5.1(而不是5.0)。
--http://lua-users.org/wiki/SimpleLuaClasses。
function class(base,ctor)
local c = {} --一个新的类实例
if not ctor and type(base) == 'function' then
ctor = base
base = nil
elseif type(base) == 'table' then
--我们的新类是基类的浅层副本!
for i,v in pairs(base) do
c[i] = v
end
c._base = base
end
--该类将是其所有对象的元表,
--并且它们将在其中查找它们的方法。
c.__index = c
--暴露可以通过()调用的构造函数
local mt = {}
mt.__call = function(class_tbl,...)
local obj = {}
setmetatable(obj,c)
if ctor then
ctor(obj,...)
else
--确保基类的任何内容都已初始化!
if base and base.init then
base.init(obj,...)
end
end
return obj
end
c.init = ctor
c.instanceOf = function(self,klass)
local m = getmetatable(self)
while m do
if m == klass then return true end
m = m._base
end
return false
end
setmetatable(c,mt)
return c
end
--------Account.lua------
--导入Class模板
require 'class'
local classname = "Account"
--声明类构造函数
Account = class(function(acc,balance)
--在此处声明实例变量。
if(balance ~= nil)then
acc.balance = balance
else
--默认值
acc.balance = 2097
end
acc.classname = classname
end)
--------Account2.lua------
local account2 = {}
account2.classname = "未命名的"
account2.balance = 2097
-----------构造函数1
do
local metatable = {
__index = account2;
}
function Account2()
return setmetatable({}, metatable);
end
end
--------Main.lua------
require 'Account'
require 'Account2'
MAX_OBJ = 5000;
test_value = 1000;
Obj_Table = {};
MODE_ACC0 = 0 --整数
MODE_ACC1 = 1 --账户
MODE_ACC2 = 2 --Account2
TEST_MODE = MODE_ACC0;
Lua_mem = 0;
function Load()
for i=1, MAX_OBJ do
if(TEST_MODE == MODE_ACC0 )then
table.insert(Obj_Table, test_value);
elseif(TEST_MODE == MODE_ACC1 )then
table.insert(Obj_Table, Account(test_value)); --Account.lua
elseif(TEST_MODE == MODE_ACC2 )then
table.insert(Obj_Table, Account2()); --Account2.lua
Obj_Table[i].balance = test_value;
end
end
end
function Purge()
--元表清除
if(TEST_MODE ~= MODE_ACC0)then
--清除阶段0:
print("将每个元素的元表设置为nil")
for i=1, MAX_OBJ do
setmetatable(Obj_Table[i], nil);
end
end
--清除阶段1:
print("将表元素设置为nil")
for i=1, MAX_OBJ do
Obj_Table[i] = nil;
end
--清除阶段2:
print("开始表删除...");
for i=1, MAX_OBJ do
原文链接 https://stackoverflow.com/questions/2733406
Main.lua:
--purge stage 0:
print("将每个元素的元表设置为nil")
for i=1, MAX_OBJ do
setmetatable(Obj_Table[i], nil);
end
根据Lua的文档,你不能通过将元表设置为nil来重置一个表的元表。这只会等同于getmetatable()
函数。因此,对象仍然保持连接。
大多数动态语言实际上不会将内存释放回系统,而是将其保留以备将来分配。在 Lua 报告内存减少之后尝试创建一些对象 - Lua 应该使用它自己保留的这些已释放的内存,这样平台内存消耗就不会增加。
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
- 如何编写 Lua 模式将字符串(嵌套数组)转换为真正的数组?
你需要强制垃圾收集器回收内存(参见
collectgarbage(“collect”)
)。