我目前正在使用IronPython,出于某种原因,当我尝试在单独的AppDomain中创建带有变量的许多ScriptScope时,我的内存使用率从未增加过GC。当我在当前的AppDomain中运行相同的代码时,垃圾收集工作正常,内存永远不会增长。下面是一个重现OutOfMemoryException的简单程序。
我还测试过设置一个大字符串变量而不是很多变量并获得相同的结果。我在.NET版本4.5.50709上运行IronPython 2.7.4,我的构建目标是x86和.NET Framework 4.在单独的AppDomain中发布未使用的ScriptScope或者这是一个内存泄漏,我需要做些什么特别的事情吗?
public static void Main()
{
var testLeak = true;
var appDomain = testLeak ? AppDomain.CreateDomain("test") : AppDomain.CurrentDomain;
var engine = Python.CreateEngine(
appDomain, new Dictionary<string, object> { { "LightweightScopes", true } });
var scriptSource = engine.CreateScriptSourceFromString("pass");
var compiledCode = scriptSource.Compile();
for (var i = 0; i < 10000; i++)
{
var scope = engine.CreateScope();
for (var j = 0; j < 100000; j++)
{
scope.SetVariable("test" + j, j);
}
compiledCode.Execute(scope);
}
}
答案 0 :(得分:1)
我自己想出了这个。如果您查看ScriptScope的源代码,这就是它覆盖MarshalByRefObject的方式:
public override object InitializeLifetimeService()
{
return (object) null;
}
这意味着永远不会在远程AppDomain中收集垃圾。我想我必须找到一种方法来使用单个ScriptEngine和ScriptScope。
答案 1 :(得分:0)
由于您只是创建AppDomain来托管PythonEngine,为什么不在使用后卸载它?这可以解决内存泄漏问题。
AppDomain.Unload(appDomain);