Tenemos un componente de servidor escrito en .Net 3.5. Se ejecuta como servicio en Windows Server 2008 Standard Edition. Funciona muy bien, pero después de algún tiempo (días) notamos desaceleraciones masivas y un conjunto de trabajo aumentado. Esperábamos algún tipo de pérdida de memoria y usamos WinDBG/SOS para analizar volcados del proceso. Desafortunadamente, el GC Heap no muestra ninguna fuga, pero notamos que el montón del código JIT ha crecido de 8 MB después del inicio a más de 1 GB después de unos días..NET JIT Code Cache leakking?
No utilizamos ninguna técnica de generación de código dinámico por nuestra cuenta. Usamos Linq2SQL que es conocido por la generación de código dinámico, pero no sabemos si puede causar tal problema.
La pregunta principal es si hay alguna técnica para analizar el volcado y comprobar de dónde vienen todos estos bloques de Heap de Host Code que se muestran en los volcados de WinDBG.
[Actualización]
Por el momento nos hizo un poco más de análisis y tenía Linq2SQL como probable sospechoso, sobre todo porque no usamos consultas precompilados. El siguiente programa de ejemplo crea exactamente el mismo comportamiento donde más y más bloques de Heap de Host Code se crean a lo largo del tiempo.
using System;
using System.Linq;
using System.Threading;
namespace LinqStressTest
{
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 100; ++ i)
ThreadPool.QueueUserWorkItem(Worker);
while(runs < 1000000)
{
Thread.Sleep(5000);
}
}
static void Worker(object state)
{
for (int i = 0; i < 50; ++i)
{
using (var ctx = new DataClasses1DataContext())
{
long id = rnd.Next();
var x = ctx.AccountNucleusInfos.Where(an => an.Account.SimPlayers.First().Id == id).SingleOrDefault();
}
}
var localruns = Interlocked.Add(ref runs, 1);
System.Console.WriteLine("Action: " + localruns);
ThreadPool.QueueUserWorkItem(Worker);
}
static Random rnd = new Random();
static long runs = 0;
}
}
Cuando reemplazamos la consulta Linq por una precompilada, el problema parece desaparecer.
@pitchfork - un poco al azar. ¿Intentó desactivar el seguimiento de cambios en 'DataContext'? 'ctx.ObjectTrackingEnabled = false' como la primera línea dentro de la instrucción using? –