如何防止CompileAssemblyFromSource泄漏内存?
收藏

我有一些C#代码使用CSharpCodeProvider.CompileAssemblyFromSource在内存中创建一个程序集。在对程序集进行垃圾回收之后,我的应用程序使用的内存比创建程序集之前要多。我的代码在ASP.NET Web应用程序中,但是我在WinForm中重复了此问题。我正在使用System.GC.GetTotalMemory(true)和Red Gate ANTS Memory Profiler来测量增长(带有示例代码的大约600个字节)。

从我完成的搜索中,听起来像泄漏是由于创建了新类型,而不是实际上是我持有引用的任何对象。我发现的某些网页中提到了有关AppDomain的内容,但我不理解。有人可以解释这里发生了什么以及如何解决吗?

以下是一些泄漏的示例代码:

private void leak()
{
    CSharpCodeProvider codeProvider = new CSharpCodeProvider();
    CompilerParameters parameters = new CompilerParameters();
    parameters.GenerateInMemory = true;
    parameters.GenerateExecutable = false;

    parameters.ReferencedAssemblies.Add("system.dll");

    string sourceCode = "using System;\r\n";
    sourceCode += "public class HelloWord {\r\n";
    sourceCode += "  public HelloWord() {\r\n";
    sourceCode += "    Console.WriteLine(\"hello world\");\r\n";
    sourceCode += "  }\r\n";
    sourceCode += "}\r\n";

    CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, sourceCode);
    Assembly assembly = null;
    if (!results.Errors.HasErrors)
    {
        assembly = results.CompiledAssembly;
    }
}

更新1:此问题可能有关:动态加载和卸载使用CSharpCodeProvider生成的dll

更新2:尝试更多地了解应用程序域,我发现:什么是应用程序域-.Net初学者的解释

更新3:为澄清起见,我正在寻找一种解决方案,该解决方案应提供与上面的代码相同的功能(编译并提供对生成的代码的访问)而又不会泄漏内存。看来解决方案将涉及创建新的AppDomain和封送处理。

最佳答案

不支持卸载程序集。有关为什么的一些信息可以在这里找到。 在此处可以找到有关使用AppDomain的一些信息。

    公众号
    关注公众号订阅更多技术干货!