今天早上据说一件事情让我以为很诡异的事情:公司线上的一款游戏,加载一份配置资源后,内存涨了几十M,而后内存再也下不来了。由于好奇,因此要来了最大的一个配置文件(4.5M,去除空格与换行后的大小),进行测试。最终发现,内存实际上是能够被释放的,不过须要注意如下的规则。html
同时,为了证实luac 与 luajit 表现一致,我同时也使用了 luajit 进行了测试。json
前往下载页面 http://luajit.org/download.html ,而后下载最新版本 函数
在开始菜单中找到 Visual Studio的 Command Prompts测试
进入下载好的 luajit 解压目录 LuaJIT-2.1.0-beta2/src 运行 msvcbuild.batui
重点在模块的编写,模块编写的方法致使了释放内存的不一样。lua
当 require 准备加载一个 lua 文件时,它会先检测 package.loaded[modulename] 是否返回 false,若是不是 false,它直接返回相应存储的值,不然查找并加载相应的文件,找不到就报错。spa
当加载的一个 lua 模块,若是没有 return 任何值时,package.loaded[modulename] 值为 true。3d
当加载一个 lua 模块,返回一个 table 时,package.loaded[modulename] 值为 table。code
我拿到的 lua 文件是这样定义的,本来是一个json,将其转为lua的,将全部数据赋值给一个变量(require 以后多了一个全局变量),这样 package.loaded[modulename] 为 true,重置这个值并不会回收内存,须要同时清理全局变量(将相应变量置为 nil),才能够实现内存的回收。htm
示例代码:
local a = require(“b”)
-- clear
a = nil
package.loaded[“b”] = nil
collectgarbage()
print(collectgarbage("count") / 1024)
能够针对上面的函数,封装一个unrequire
function unrequire(m) package.loaded[m] = nil _G[m] = nil end
实际测试的示例
上面的20.xx是M,你没看错。一个约4.5M的 lua 文件,被 require 进内存后,lua 所占用的内存大小变为 20M。为何会这么大,有待进一步从源码中寻找答案。