I'm working on an module of MVVM-application based on the MVVMLight.Messenger and Roslyn scripts. Idea is to give to user ability to modify business logic, attach and detach user scripts from objects. The problem is that when you frequently change the executable code of scripts, the size of the memory occupied by the application grows. I use code from this answer.
var initial = CSharpCompilation.Create("Existing")
.AddReferences(MetadataReference.CreateFromFile(typeof(object).Assembly.Location))
.AddSyntaxTrees(SyntaxFactory.ParseSyntaxTree(CHANGED_METHOD_BODY));
var method = initial.GetSymbolsWithName(x => x == "Script").Single();
// 1. get source
var methodRef = method.DeclaringSyntaxReferences.Single();
var methodSource = methodRef.SyntaxTree.GetText().GetSubText(methodRef.Span).ToString();
// 2. compile in-memory as script
var compilation = CSharpCompilation.CreateScriptCompilation("Temp")
.AddReferences(initial.References)
.AddSyntaxTrees(SyntaxFactory.ParseSyntaxTree(methodSource, CSharpParseOptions.Default.WithKind(SourceCodeKind.Script)));
using (var dll = new MemoryStream())
using (var pdb = new MemoryStream())
{
compilation.Emit(dll, pdb);
// 3. load compiled assembly
assembly = Assembly.Load(dll.ToArray(), pdb.ToArray());
var methodBase = assembly.GetType("Script").GetMethod(method.Name, new Type[0]);
// 4. get il or even execute
MethodBody il = methodBase.GetMethodBody();
return methodBase;
}
It happens because I execute Assembly.Load every time I compile a changed script. The old assembly remains apparently in the CLR. Are there any approaches to implement changing logic and prevent memory leaks?