如何用Lua追踪内存泄漏/未释放的内存?
2012-2-1 18:34:56
收藏:0
阅读:134
评论:2
我正在使用Lua和cocos2d-x进行开发。最近,我使用了Instruments,发现有一定量的内存被遗弃了:cocos2d-x在其自己的自动释放池中释放对象,但是我仍然有来自Lua的引用。如何找出这些引用是何时被创建的?我需要释放那些内存以避免留下未释放的内存分配问题。我想到的唯一方法是使用一些Lua调试器来查找nil
Lua指针后的引用。如果我知道哪个Lua引用保存着指针,那么我就可以手动释放它。
原文链接 https://stackoverflow.com/questions/9099791
点赞
stackoverflow用户763397
我也曾遇到过这个问题。
不幸的是,尽管 Lua 脚本引擎引用了对象,Cocos2d-x 仍可以销毁 CCObjects。它似乎绑定不完美。
您可以通过创建一个 CCNode 静态包并在场景中添加一个不同的 CCNode,然后将其删除(触发清除),然后等待一帧更新来测试这一点。尽管具有有效的 Lua 引用,原始的 CCNode 对象将消失,并且在 Lua 中调用其方法将抛出错误,尽管对象~= nil。
您可以通过创建一个 CCMutableArray_CCObject__ 对象并将 CCObjects 添加到其中来解决此问题。这将增加这些对象的引用计数,并且 CCMutableArray_CCObject__ 将不会被 gc'ed,除非 Lua 引用也被 gc'ed。
2013-06-04 20:05:26
评论区的留言会收到邮件通知哦~
推荐文章
- 如何在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 模式将字符串(嵌套数组)转换为真正的数组?
你的问题表达得有点奇怪。但据我了解,你的Lua脚本中引用了在外部代码中分配的对象。只要Lua继续引用这些对象,外部代码就不会释放这些资源。而你认为这些资源应该被释放。
你应该先检查你的Lua接口代码是否使用元方法来正确清除引用。也就是说,当Lua完成对一个对象引用的操作后,附加了一个元方法(
__gc
),该方法将告知外部代码,Lua已经完成了对该对象的使用。我假设这段代码是存在且正常运作的。你自己也应该验证一下。
在这个假设的基础上,你所看到的结果有两种可能:
你的Lua代码已经完成了使用它所有的引用,但是还没有清理它们。这意味着,Lua脚本不再将引用存储在任何局部变量、全局变量等中。在这种情况下,发生的情况是Lua的垃圾回收器还没有运行并清理掉所有事物。所以你需要使用
lua_gc(L, LUA_GCCOLLECT, 0);
来清理它们。如果是这种情况,那么运行此函数后,Lua中的所有引用都应该已经被清理了。你的Lua代码仍然有潜在的对外部对象的引用。
处理情况#2是困难的。这是Lua代码的责任,要有遵循原则的行为。它应该在需要引用这些东西时存储引用,然后在稍后忘记这些引用。我的意思是,不要将值存储在非局部变量中(我也指避免被嵌套的函数定义使用的局部变量)。
没有办法找到这些引用仍然存在的位置。毕竟,Lua值不一定有名称。此外,Lua并没有真正给你一种方法来迭代
lua_State
中的每个可能变量。即使有办法,当然也没有一种方式可以简单地清除这些引用。毕竟,Lua代码仍然可以使用它们。如果清除了它们,当Lua尝试与这些对象通话时,Lua代码会崩溃。所以,即使你可以做你想做的事情,也是适得其反的。我建议你采取以下三种方法之一来处理这个问题:
在你的脚本中增加纪律性。确保你知道所有的非Lua对象的存储位置。当应该释放这些对象时,确保这些对象被释放了。知道你把这些外部对象放在哪里,并确保在适当的时间释放它们。我的意思是,只需使用'nil'来覆盖它们的值即可将其释放。
在你的脚本和源代码之间增加一层隔离。而不是直接将Cocos2D-X对象的指针直接传递给Lua,将指针传递给一个特殊对象,该对象可能包含对Cocos2D-X对象的引用。这样,你可以通过告诉这个控制对象放弃它的引用来直接控制这些对象何时释放。如果你调用一个空的控制对象,函数将返回......无害的内容(这样你就不会崩溃)。显然,Lua应该有一个函数来查看它是否是有效的控制对象。
在Lua中做任何你想做的事情,但是在释放资源时,破坏整个Lua状态。你当前的方法非常细粒度。Lua会创建一些资源,然后Lua决定它们何时消失。更严格的资源管理计划是,Lua脚本装载一些资源和引用资源。但是,当释放所有这些资源时,你只需使用
lua_close
关闭lua_State
本身即可。这将释放所有引用,从而释放这些资源。问题解决了。