CsharpCodeProvider内存泄漏

时间:2012-04-09 18:50:50

标签: c# .net csharpcodeprovider

有人帮助我在运行时使用计时器运行一些代码,但过了一段时间我发现它只是使用内存而不是释放它。

我听说过有关AppDomain的一些内容,但我没有弄清楚在哪里使用它。

AppDomain会帮我解决内存泄漏问题吗?还有什么能帮到我吗?

PS:GC.Collect()无济于事。 我确定问题是,因为我做了一些测试,在运行问题时观察内存,如果我禁用Scripter它保持相同的ammount(基本上),如果我用一些代码启动计时器来执行它保持增加并且可以在几分钟后使用500k +的内存,所以是的,我确定问题出在CSharpCodeProvider只是使用内存。

这是我的实际代码,所以如果有人可以帮我解决这个问题会很棒。

//It is executed in a timer of 500 ms
private void Run()
{
    foreach (Code ph in codeList)
    {
        Code p = ph;

        new Thread(delegate()
        {
            if (Monitor.TryEnter(p))
            {
                Scripter script = new Scripter();
                script.Compile(p.Code);
                Monitor.Exit(p);
            }
        }) { IsBackground = true }.Start();
    }
}

//That's my compile code
public bool Compile(string script)
{
    CSharpCodeProvider codeprovider = new CSharpCodeProvider();
    ICodeCompiler icc = codeprovider.CreateCompiler();
    CompilerParameters cp = new CompilerParameters();

    cp.ReferencedAssemblies.Add("System.dll");
    cp.ReferencedAssemblies.Add(System.Reflection.Assembly.GetExecutingAssembly().Location);

    cp.TreatWarningsAsErrors = false;

    cp.MainClass = "CodesRun";
    cp.CompilerOptions = "/target:library /optimize";
    cp.GenerateExecutable = false;
    cp.GenerateInMemory = false; //it was true, but same problem

    TempFileCollection tfc = new TempFileCollection(Application.StartupPath, false);
    CompilerResults cr = new CompilerResults(tfc);

    cr = icc.CompileAssemblyFromSource(cp, script);

    if (cr.Errors.Count > 0)
    {
        //Error
    }
    else
    {
        Assembly assembly = cr.CompiledAssembly;
        IScript teste = (IScript)assembly.CreateInstance("CodesRun.Script");
        teste.Run();
    }
    tfc.Delete();
    codeprovider.Dispose();

    return true;
}

1 个答案:

答案 0 :(得分:0)

尝试使用using指令完成对象的处理。例如:

using( Scripter script = new Scripter() ){
   script.Compile(p.Code);
   Monitor.Exit(p);
}

这可能无法解决您的泄漏问题,但它应该会减少您的内存占用(即您应该尽快看到内存被回收)。

就像@Andrew Barber所说,你应该使用内存分析工具来验证是否存在泄漏。我们使用AQTime,但它已付费(但不是太贵)。讨论了免费选项here