无法从内存中清除Lua元表对象?

无法从内存中清除Lua元表对象?,lua,oop,memory-management,Lua,Oop,Memory Management,我使用的是一个专有平台,可以在屏幕上实时报告内存使用情况。我决定使用一个Class.lua,我在 然而,当使用一个简单的Account类清除由此创建的对象时,我注意到内存问题。具体地说,我将从使用的146k内存开始,创建一个类的1000个对象,该类只包含一个整数实例变量,并将每个对象存储到一个表中。 现在使用的内存是300k 然后我将退出,遍历表并将表中的每个元素设置为nil。但是,我永远不会得到146k,通常在这之后,我会使用210k或类似的东西。如果在同一会话期间再次运行加载序列,则不会超过

我使用的是一个专有平台,可以在屏幕上实时报告内存使用情况。我决定使用一个Class.lua,我在

然而,当使用一个简单的Account类清除由此创建的对象时,我注意到内存问题。具体地说,我将从使用的146k内存开始,创建一个类的1000个对象,该类只包含一个整数实例变量,并将每个对象存储到一个表中。 现在使用的内存是300k

然后我将退出,遍历表并将表中的每个元素设置为nil。但是,我永远不会得到146k,通常在这之后,我会使用210k或类似的东西。如果在同一会话期间再次运行加载序列,则不会超过300k,因此不会出现内存泄漏

我曾尝试在一个表中创建1000个整数,并将它们设置为nil,这会返回146k

此外,我还尝试了一个更简单的类文件(Account2.lua),它不依赖于class.lua。这仍然会导致内存碎片,但不像使用Class.lua的内存碎片那么多

有人能解释一下这是怎么回事吗?如何清除这些对象并恢复内存

这是密码 --------类lua------

--------卢阿------

--------会计2.lua------

--------梅因·卢阿------


--更新 我已经用下面评论中的建议更新了代码,并将在今天晚些时候发布我的发现


--更新2 我已经试过上面的代码了,但似乎collectgarbage(“count”)报告lua在所有三种情况下都会返回所有内存。 这是我收集垃圾的结果(“计数”)

ACC0 -启动时:使用25.567K -负载:使用89.334K -吹扫时:使用25.567K

ACC1 -启动时:使用25.567K -负载:使用440.567k -吹扫时:使用25.567K

ACC2 -启动时:使用25.327K -负载:使用245.34K
-清除时:使用了25.327K

您需要强制垃圾收集器回收内存(请参阅)。

Main.lua


    --purge stage 0: 
    print("set each elements metatable to nil")
    for i=1, MAX_OBJ do
        setmetatable(Obj_Table[i], nil);
    end


根据,无法通过尝试将tables元表设置为nil来重置该元表。它只等于函数
getmetatable()
。所以对象一直被链接。

大多数动态语言并不会真正将内存释放回系统,而是让它为将来的分配做好准备。在Lua报告内存减少后尝试创建一些对象-Lua应该使用它保留给自己的释放内存,平台内存消耗不会增加。

您是否尝试通过
collectgarbage(“collect”)
强制垃圾收集?请注意,您可能需要在一行中多次调用它以收集元表。我通常在循环中运行
“collect”
,而
“count”
值则不断变小。请注意,除非您“现在”需要内存,否则不需要强制垃圾收集。您还应该打印
collectgarbage(“count”)
以及您的平台报告。如果Lua说垃圾被释放了,那么问题在于你的平台(或者它如何使用Lua)——而不是你的Lua代码。嗨,Alexander,Lua的内置内存报告似乎告诉我内存被释放了,但平台内存报告却不是这样说的。我不认为有任何明显的证据表明它是平台,除非我在上面的代码中遗漏了什么。谢谢大家的建议!

--Import Class template
require 'class'
local classname = "Account" 
    --Declare class Constructor
    Account = class(function(acc,balance)
    --Instance variables declared here.
         if(balance ~= nil)then
                     acc.balance = balance
                    else
                     --default value
                     acc.balance = 2097
                    end
                    acc.classname = classname
                 end)

local account2 = {}

account2.classname  = "unnamed"
account2.balance  = 2097

-----------Constructor 1
do
 local metatable = {
  __index = account2;
 }

 function Account2()
  return setmetatable({}, metatable);
 end
end

require 'Account'
require 'Account2'

MAX_OBJ    = 5000;
test_value = 1000;
Obj_Table = {};
MODE_ACC0 = 0 --integers
MODE_ACC1 = 1 --Account
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()
    --metatable purge
    if(TEST_MODE ~= MODE_ACC0)then
      --purge stage 0: 
      print("set each elements metatable to nil")
      for i=1, MAX_OBJ do
        setmetatable(Obj_Table[i], nil);
      end
    end 

    --purge stage 1: 
    print("set table element to nil")
    for i=1, MAX_OBJ do
      Obj_Table[i] = nil;
    end 

    --purge stage 2: 
    print("start table.remove...");
    for i=1, MAX_OBJ do
    table.remove(Obj_Table, i);
    end 
    print("...end table.remove");

    --purge stage 3: 
    print("create new object_table {}");
    Obj_Table= {};

    --purge stage 4: 
    print("collectgarbage('collect')");
    collectgarbage('collect');


end

--Loop callback, called every tick
function OnUpdate()
   Lua_mem = collectgarbage('count');
   collectgarbage('collect');
end
--Loop rendering callback

function OnRender()
   DrawText(Lua_mem );
end
-------------------
--NOTE:
--code starts in idle awaiting input from user
--On first input, runs Load(), on exit runs Purge()
--Where DrawText() draws the string parameter passed, to screen.

    --purge stage 0: 
    print("set each elements metatable to nil")
    for i=1, MAX_OBJ do
        setmetatable(Obj_Table[i], nil);
    end