CSharpCodeProvider.CompileAssemblyFromSourceを使用してメモリ内にアセンブリを作成しているC#コードがあります。アセンブリがガベージコレクションされた後、アプリケーションはアセンブリを作成する前よりも多くのメモリを使用します。私のコードはASP.NETWebアプリにありますが、この問題をWinFormに複製しました。System.GC.GetTotalMemory(true)とRed Gate ANTS Memory Profilerを使用して、増加を測定しています(サンプルコードで約600バイト)。
私が行った検索から、リークは新しいタイプの作成に起因しているように見えますが、実際には、参照しているオブジェクトからではありません。私が見つけたいくつかのWebページは、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を使用して生成されたaadllを動的にロードおよびアンロードします
更新2:アプリケーションドメインをもっと理解しようとすると、私はこれを見つけました:アプリケーションドメインとは何ですか-.Net初心者のための説明
更新3:明確にするために、メモリリークを発生させることなく、上記のコードと同じ機能(生成されたコードのコンパイルとアクセスの提供)を提供するソリューションを探しています。このソリューションには、新しいAppDomainの作成とマーシャリングが含まれるようです。