Tengo un código C# que usa CSharpCodeProvider.CompileAssemblyFromSource para crear un ensamblaje en la memoria. Después de que el ensamblado se recolectó como basura, mi aplicación usa más memoria de la que tenía antes de crear el ensamblaje. Mi código está en una aplicación web ASP.NET, pero he duplicado este problema en WinForm. Estoy usando System.GC.GetTotalMemory (true) y Red Gate ANTS Memory Profiler para medir el crecimiento (alrededor de 600 bytes con el código de muestra).¿Cómo puedo evitar que CompileAssemblyFromSource pierda memoria?
A partir de la búsqueda que he hecho, parece que la fuga proviene de la creación de nuevos tipos, no de ningún objeto al que me refiero. Algunas de las páginas web que he encontrado han mencionado algo sobre AppDomain, pero no entiendo. ¿Puede alguien explicar qué está pasando aquí y cómo solucionarlo?
He aquí algunos ejemplos de código de fugas:
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;
}
}
Actualización 1: Esta pregunta puede estar relacionada: Dynamically loading and unloading a a dll generated using CSharpCodeProvider
Actualización 2: Tratar de entender dominios de aplicación más, me encontré con esto: What is an application domain - an explanation for .Net beginners
Actualización 3: Para aclarar, estoy buscando ng para una solución que proporciona la misma funcionalidad que el código anterior (compilar y proporcionar acceso al código generado) sin pérdida de memoria. Parece que la solución implicará la creación de un nuevo dominio de aplicación y clasificación.
pregunta muy fresco. Tendré un ejemplo de cómo hacer esto usando otro dominio de aplicación para el final de hoy (actualmente estoy almorzando, luego volviendo al trabajo ...). – Charles
¿Qué piensas hacer con el conjunto resultante? ¿Es solo para una ejecución de una vez o vas a esperar? – madaboutcode
@LightX Voy a conservarlo por un tiempo e invocar a los miembros según sea necesario, pero cuando haya una nueva versión del código fuente disponible, querré volcarlo y crear un nuevo ensamblado basado en el nuevo código Sin la corrección AppDomain, este ciclo de creación repetida de ensamblajes (aunque dejo de hacer referencia a las versiones anteriores) hace que el uso de la memoria crezca. – Nogwater