J'ai du code C# qui utilise CSharpCodeProvider.CompileAssemblyFromSource pour créer un assembly en mémoire. Une fois l'assemblage collecté, mon application utilise plus de mémoire qu'avant la création de l'assembly. Mon code est dans une application Web ASP.NET, mais j'ai dupliqué ce problème dans un formulaire WinForm. J'utilise System.GC.GetTotalMemory (true) et Red Hat ANTS Memory Profiler pour mesurer la croissance (environ 600 octets avec l'exemple de code). De la recherche que j'ai faite, on dirait que la fuite vient de la création de nouveaux types, pas vraiment d'aucun des objets auxquels je tiens des références. Certaines des pages Web que j'ai trouvées ont mentionné quelque chose sur AppDomain, mais je ne comprends pas. Quelqu'un peut-il expliquer ce qui se passe ici et comment y remédier?Comment puis-je empêcher CompileAssemblyFromSource de fuir la mémoire?
Voici quelques exemples de code pour une fuite:
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;
}
}
Mise à jour 1: Cette question peut être liée: Dynamically loading and unloading a a dll generated using CSharpCodeProvider
Mise à jour 2: Essayer de comprendre les domaines d'application plus, je trouve ceci: What is an application domain - an explanation for .Net beginners
Mise à jour 3: Pour clarifier, je suis looki ng pour une solution qui fournit la même fonctionnalité que le code ci-dessus (compilation et fourniture d'accès au code généré) sans perte de mémoire. Il semble que la solution impliquera la création d'un nouvel AppDomain et d'un marshaling.
question très cool. Je vais avoir un exemple de la façon de le faire en utilisant un autre AppDomain d'ici la fin de la journée (je déjeune actuellement, puis je retourne au travail ...). – Charles
Que comptez-vous faire avec l'assemblage résultant? Est-ce juste pour une exécution ponctuelle ou allez-vous vous en occuper? – madaboutcode
@LightX Je vais m'y accrocher pendant un moment et en invoquer des membres si nécessaire, mais quand une nouvelle version du code source sera disponible, je vais vouloir la vider et créer un nouvel assemblage basé sur le nouveau code. Sans le correctif AppDomain, ce cycle de création répétée d'assemblys (même si j'arrête de référencer les anciennes versions) entraîne une augmentation de l'utilisation de la mémoire. – Nogwater