我在LuaJIT中编写了一个应用程序,使用第三方GUI框架(基于FFI)+一些额外的自定义FFI调用。该应用程序在运行后很快就会突然失去部分功能,而且我非常有信心因为某些未固定的对象被GC编辑。我假设他们仅引用了C world 1 ,因此Lua GC认为他们没有引用并且可以释放它们。问题是,我不知道众多用户数据中哪些在Lua端没有被引用(取消固定)?
为了确认我的理论,我通过以下方式运行了禁用GC的应用程序:
collectgarbage 'stop'
并且,对于这一行,该应用程序完美地运行 long 超过它之前被破坏的点。显然,这是一个丑陋的解决方法,我更喜欢启用GC,并且应用程序仍能正常工作......
我想找出哪个未固定的对象(我假设用户数据)得到GCed,所以我可以在Lua端正确固定它,以防止它过早地进行GC。因此,我的问题是:
(如何)我可以跟踪在我的应用失去功能时收集了哪些用户数据对象?
一个问题是,AFAIK,LuaJIT FFI已经分配了自定义__gc
处理程序,因此我无法添加自己的处理程序,因为每个对象只能有一个。无论如何,这个框架太大了,我不能尝试在其中的每个可以想象的地方添加__gc
。而且,我已经淘汰了最明显被怀疑的"代码中的位置,通过从某些变量中删除local
- 从而使它们成为_G
的一部分,因此我假设不能使用GC。 (或者这还不够?)
1 具体来说,是WinAPI。
答案 0 :(得分:0)
现在,我已经为我的一些对象添加了一些ffi.gc()处理程序(打印一些容易看到的ALL-CAPS消息),然后添加了一些急切的collectgarbage()调用以尽快触发问题尽可能:
ffi.gc(foo, function()
print '\n\nGC FOO !!!\n\n'
end)
[...]
collectgarbage()
事实上,这暴露了一些我没想到的GCing。具体来说,它让我发现a note in luajit's FFI docs,这在我的案例中肯定是相关的:
请注意,[C]指针[...] 不是,后面是垃圾收集器。所以例如如果你为一个指针分配一个cdata数组,只要指针仍在使用中,你必须保持cdata对象保持数组[在Lua中]。