Lua模块的加载与内存释放

简介: 今天早上听说一件事情让我觉得很诡异的事情:公司线上的一款游戏,加载一份配置资源后,内存涨了几十M,然后内存再也下不来了。因为好奇,所以要来了最大的一个配置文件(4.5M,去除空格与换行后的大小),进行测试。

今天早上听说一件事情让我觉得很诡异的事情:公司线上的一款游戏,加载一份配置资源后,内存涨了几十M,然后内存再也下不来了。因为好奇,所以要来了最大的一个配置文件(4.5M,去除空格与换行后的大小),进行测试。最终发现,内存其实是可以被释放的,不过需要注意以下的规则。

 

同时,为了证明luac 与 luajit 表现一致,我同时也使用了 luajit 进行了测试。

前往下载页面 http://luajit.org/download.html  ,然后下载最新版本

image

在开始菜单中找到 Visual Studio的 Command Prompts

image

进入下载好的 luajit 解压目录 LuaJIT-2.1.0-beta2/src  运行 msvcbuild.bat

 

重点在模块的编写,模块编写的方法导致了释放内存的不同。

 

当 require 准备加载一个 lua 文件时,它会先检测 package.loaded[modulename] 是否返回 false,如果不是 false,它直接返回相应存储的值,否则查找并加载相应的文件,找不到就报错。

 

当加载的一个 lua 模块,如果没有 return 任何值时,package.loaded[modulename] 值为 true。

当加载一个 lua 模块,返回一个 table 时,package.loaded[modulename] 值为 table。

 

我拿到的 lua 文件是这样定义的,原本是一个json,将其转为lua的,将所有数据赋值给一个变量(require 之后多了一个全局变量),这样 package.loaded[modulename] 为 true,重置这个值并不会回收内存,需要同时清理全局变量(将相应变量置为 nil),才可以实现内存的回收。

 

示例代码:

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。为什么会这么大,有待进一步从源码中寻找答案。

目录
相关文章
浅谈基于openresty(nginx+lua)开发轻量级,按流量控制的灰度模块(下)
浅谈基于openresty(nginx+lua)开发轻量级,按流量控制的灰度模块
158 0
|
24天前
|
JSON Ubuntu 开发者
ubuntu 22安装lua环境&&编译lua cjson模块
通过上述步骤,可以在 Ubuntu 22.04 系统上成功安装 Lua 环境,并使用 LuaRocks 或手动编译的方式安装 lua-cjson 模块。本文详细介绍了每一步的命令和操作,确保每一步都能顺利完成,适合需要在 Ubuntu 系统上配置 Lua 开发环境的开发者参考和使用。
112 13
|
3月前
|
缓存 监控 Java
在使用 Glide 加载 Gif 动画时避免内存泄漏的方法
【10月更文挑战第20天】在使用 Glide 加载 Gif 动画时,避免内存泄漏是非常重要的。通过及时取消加载请求、正确处理生命周期、使用弱引用、清理缓存和避免重复加载等方法,可以有效地避免内存泄漏问题。同时,定期进行监控和检测,确保应用的性能和稳定性。需要在实际开发中不断积累经验,根据具体情况灵活运用这些方法,以保障应用的良好运行。
|
3月前
|
C++
析构造函数就是为了释放内存,就是在局部指针消失前释放内存,拷贝构造函数就是以构造函数为模块,在堆里面新开一块,同一个变量在堆里面的地址
本文讨论了C++中构造函数和析构函数的作用,特别是它们在管理动态内存分配和释放中的重要性,以及如何正确地实现拷贝构造函数以避免内存泄漏。
51 2
|
6月前
|
NoSQL Redis C++
c++开发redis module问题之在复杂的Redis模块中,特别是使用第三方库或C++开发时,接管内存统计有哪些困难
c++开发redis module问题之在复杂的Redis模块中,特别是使用第三方库或C++开发时,接管内存统计有哪些困难
|
6月前
|
监控 Python
paramiko 模块 ---Python脚本监控当前系统的CPU、内存、根目录、IP地址等信息
paramiko 模块 ---Python脚本监控当前系统的CPU、内存、根目录、IP地址等信息
|
7月前
|
消息中间件 存储
【消息队列开发】 实现内存加载
【消息队列开发】 实现内存加载
|
7月前
|
Java 程序员 Linux
探索C语言宝库:从基础到进阶的干货知识(类型变量+条件循环+函数模块+指针+内存+文件)
探索C语言宝库:从基础到进阶的干货知识(类型变量+条件循环+函数模块+指针+内存+文件)
61 0
|
Linux Go API
MemoryModule内存反射DLL加载探索
MemoryModule内存反射DLL加载探索
[√]lua加载dll
[√]lua加载dll
144 0