Ich benutze eine sehr einfache asp.net mvc-Anwendung mit Entity Framework 6.0.2, .Net 4.5.1:
public class HomeController : Controller
{
public ActionResult Index()
{
int count;
using (var db = new LocalContext())
{
count = db.Counters.Count();
}
return View(count);
}
}
public class Counter
{
public int Id { get; set; }
}
public class LocalContext : DbContext
{
public DbSet<Counter> Counters { get; set; }
}
Wenn ich einen Belastungstest mache, bekomme ich schließlich eine Out of Memory Exception. ( tinyget -srv:localhost -port:<port> -uri:/home/index/ -threads:30 -loop:5000
). Im Leistungsmonitor sehe ich die Generation 2 Heap stetig wachsen. Wenn ich einen kleineren Loop-Wert verwende (etwa 500), wird die Größe größer, bis tinyget aufhört. Dann bleibt die Größe des Heaps gleich (für mindestens 20 Minuten, danach habe ich den Server gestoppt).
Was mache ich falsch?
BEARBEITEN
Also habe ich Simon Mouriers Vorschlag ausprobiert und den EF-Code weggelassen. Dann habe ich keine Speicherprobleme. Also dachte ich, wenn ich Release statt Debug benutze, wird es einen Unterschied machen. Und es hat! Speicher wurde nach einer Weile freigegeben und ich konnte die Seite stark belasten. Dann wechselte ich wieder auf Debug um zu sehen, ob ich mehr Infos bekommen konnte und ... selbst im Debug-Modus keine Probleme mehr. FML, ich habe einen Tag daran gearbeitet und kann es jetzt nicht mehr reproduzieren.
In Ihrem Fall müsste die intern verwaltete Klasse, die von DbContext erbt, IDisposable implementieren und innerhalb des LocalContext Folgendes hinzufügen:
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// Manage any native resources.
}
//Handle any other cleanup.
}
Ohne den Aufruf zum Verfügen zu überschreiben, ruft die using-Anweisung nur Dispose () für die Basisklasse auf, während Sie die Eltern- und Basisklasse entsorgen müssen.