- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我发现我在 C#/Lua LuaInterface 项目中有严重的内存泄漏。我用 C# 编写了一个简单的测试函数,它每 0.5 秒从 Lua 循环调用一次。我可以看到 Lua 内存使用量随着每个循环而增加。我最新的 C# 端代码是
public LuaTable testMemTable()
{
LuaTable tabx = m_lua.GetTable("tabx");
if (tabx != null)
{
tabx.Dispose();
tabx = null;
GC.Collect();
GC.WaitForPendingFinalizers();
}
m_lua.NewTable("tabx");
tabx = m_lua.GetTable("tabx");
for (int i = 0; i < 20000; i++)
tabx[i] = i * 10;
return tabx;
}
while true do
myAPILibs.testMemTable()
if tabx ~= nil then
print(string.format("Size = %d", #tabx))
else
print(string.format("Size = nil"))
end
print(tabx, tabx[111])
myAPILibs.sleep(500)
print("Before ", collectgarbage("count") * 1024)
collectgarbage("collect")
print("After ", collectgarbage("count") * 1024)
end
最佳答案
我需要吐槽一下 LuaInterface,因为它让这个问题很难解决——在某些情况下,甚至不可能不泄漏内存。
LuaInterface(和 NLua)中的 CLR 对象代理不提供释放 Lua 引用的终结器。1 您必须处理每个引用 Lua 对象的 CLR 对象。如果你忘记了一次,Lua 对象永远不会被垃圾回收。
更糟糕的是,您无法正确处理从 Lua 调用的 CLR 方法返回的引用。如果您在归还它之前处理了该引用,那么它就消失了,您将无法再归还它。如果不释放它,CLR 引用就会泄露。您可以通过一些代码练习来正确处理引用,但完全没有理由要求您进行此类工作。
现在让我离开我的肥皂盒并解决您的代码。
在您的所有方法中都有很多地方会泄漏这些对象。您对 GetTable()
的使用掩盖了您对其工作原理的误解。每次调用此方法时,都会获得一个新的 CLR 对象,该对象引用该 Lua 全局变量所引用的 Lua 表。您对它的使用似乎假设您可以执行 m_lua.GetTable("tabx").Dispose()
并完成一些事情——所有这些都是创建一个新的 CLR 引用,然后只处理那个引用。换句话说,这是一种什么都不做的昂贵方式。
每次调用 GetTable()
应该有相应的处置 (或使用 C# 的 using
block 为您进行处理)。
澄清一下,处理 CLR LuaTable
对象不会破坏 Lua 表!它所做的只是释放对该表的特定 CLR 引用。
这适用于每个引用 Lua 对象的 LuaInterface 类型,包括函数,这是您可能泄漏的另一个地方。
在这里,我将展示每种方法的问题,以及如何重写它来解决这些问题。
public LuaTable testMemTable()
{
// This code does nothing. You get a new reference to the Lua table
// object, and then you immediately dispose it. You can remove this
// whole chunk of code; it's a really expensive no-op.
LuaTable tabx = m_lua.GetTable("tabx");
if (tabx != null)
{
tabx.Dispose();
tabx = null;
GC.Collect();
GC.WaitForPendingFinalizers();
}
m_lua.NewTable("tabx");
// You create a new CLR object referencing the new Lua table, but you
// don't dispose this CLR object.
tabx = m_lua.GetTable("tabx");
for (int i = 0; i < 20000; i++)
tabx[i] = i * 10;
return tabx;
}
public void testMemTable()
{
m_lua.NewTable("tabx");
using (LuaTable tabx = m_lua.GetTable("tabx")) {
for (int i = 0; i < 20000; i++) {
tabx[i] = i * 10;
}
}
}
public LuaTable getNewTableCSharp()
{
// You don't dispose the function object.
var x = lua.GetFunction("getNewTableLua");
// You don't dispose the table object.
var retValTab = (LuaTable)x.Call()[0];
return retValTab;
}
getNewTableLua
函数永远不会重新分配,您实际上并没有泄漏 Lua 函数,但是每次调用此函数时,您都会泄漏 Lua 表中的一个槽,该槽包含对该函数的引用。
public LuaTable getNewTableCSharp()
{
using (var x = lua.GetFunction("getNewTableLua")) {
// Still leaks, but you can't do anything about it.
return (LuaTable)x.Call()[0];
}
}
using
block ,以确保 Lua 的 GC 可以及时收集对象。) 关于c# - LuaInterface 内存泄漏问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40456209/
我发现我在 C#/Lua LuaInterface 项目中有严重的内存泄漏。我用 C# 编写了一个简单的测试函数,它每 0.5 秒从 Lua 循环调用一次。我可以看到 Lua 内存使用量随着每个循环而
我正在尝试使用 LuaInterface 加载 .net 程序集。如果我将程序集放在与我的可执行文件(以及我的 LuaInterface.dll 和 LuaNet.dll)相同的文件夹中,那么一切都很
我是 LuaInterface 的新手,有一个非常简单的问题:如何从 C# 访问多维 lua 表中的数据?我设法读取了字符串和整数值,但对表格并不幸运。我的目标是在(虚拟)GridView 中显示多维
我在 C# 中使用 LuaInterface,并且我“导出”了一些要在 Lua 中使用的自定义 C# 类。例如: local myVector = Vector2(10, 100) 但是,当我想像本例
我正在尝试使用 LuaInterface 将 Lua 脚本接口(interface)集成到我的 C# 项目中。 . 如果我执行语法正确的代码,它会按预期工作,但是一旦在脚本中引入语法错误(或任何其他错
我正在尝试将 LuaInterface 集成到 C# 中,但当我尝试将 C# 函数绑定(bind)到 Lua 时,出现了 System.NullReferenceException 。我尝试编译和运行
我一直在尝试使用 LuaInterface 将 Lua 集成到我的托管代码中。我正在使用我下载的程序集附带的 lua51.dll,但是当我尝试创建一个新的 Lua 对象时,构造函数失败并显示 ERRO
我有一些后台 lua 代码,我在每次启动时加载它们,它们工作正常,但有什么方法可以将它们转换为 C# 吗? 这是我的元表代码: player = {} player.__index = player
使用 NLua 运行 lua 脚本时如何调用函数? (一个 LuaInterface 分支)? 例如,现在我有: lua.LoadFile("C:\\test.lua") lua.Call(); 但是
我的 C# 代码中有一个字节数组,我需要将其传递给 LuaInterface 实例。我可以在 Lua 中使用 pack(),将生成的字符串传递给 C# 并使用 System.Text.Encoding
我正在使用 LuaInterface 将 LuaInterface 集成到 C# 程序中。我希望能够编写可以在程序中访问 C# 方法的脚本。 它访问的方法在单独的“子系统”中,我想让 Lua 方法定义
有没有人知道如何编写一个返回 LuaTable 值的 C# 函数(例如 {1 = "example1", 2 = 234, "foo"= "Foo Example"} ?我测试过的所有类型都返回非 p
我将 LuaInterface 导入到控制台项目中,引用它,并编写了一个小测试脚本。当我运行它时,我得到这个: Could not load file or assembly 'LuaInterfac
我正在尝试使用 LuaInterface 2.0.3 在我的 C# 应用程序中嵌入一些 Lua 脚本功能。到目前为止,这工作得很好,但我不知道如何限制对少数指定 .Net 类的访问。默认情况下,所有
我已将 LuaInterface 项目嵌入到使用 .NET Framework 4.0 以 C# 编写的应用程序中。编译 LuaInterface 和 Lua 5.1 后,我在我的应用程序中引用了它们
我有一个 Lua 模块 ( lpack ),我需要加载到 LuaInterface 中。我已经为该项目尝试了几种不同的配置,但我似乎无法弄清楚链接。 我收到错误 unresolved external
我想传递一个 WinForm 对象给 Lua,我的代码: //Form1.cs class Form1 { private System.Windows.Forms.TextBox textBox
当我尝试使用 LuaInterface 时在 Linux 上的 Mono 上(在 Ubuntu 9.04 上使用 Mono 2.0)我得到以下异常: ** (App.exe:8599): WARNIN
我正在尝试将 Lua 连接到我正在制作的 VB.net 游戏。现在,我已经阅读了足够多的内容,知道我可以像这里看到的那样自行连接每个函数: pLuaVM.RegisterFunction("quit"
因为我的游戏,我真的很想用 Mono-usable,似乎不能在 Linux 下运行,因为 LuaInterface 是个 SCSS (参见 the relevant SO thread 了解更多信息)
我是一名优秀的程序员,十分优秀!