Ich habe ein relativ großes Entity-Framework-Modell (ungefähr ~ 300 Tabellen), für das ich Sichten vorreite, um die Abfrage- / Anwendungsleistung zu verbessern.
Wenn die Anwendung nur minimal belastet wird, nehme ich innerhalb von 6-7 Stunden den Speicherverbrauch innerhalb der Anwendung allmählich zu. Bei Erreichen von ca. 4GB wird der Anwendungspool zurückgesetzt und der Prozess wird wiederholt.
Abbildung 1: Anzeigen des Anwendungsspeicherverbrauchs im Verlauf von 8-9 Stunden
Diese Anwendung verwendet eine Variation des Repository-Musters und stellt sicher, dass Instanzen meines ObjectContext in kürzester Zeit für jede Transaktion instanziiert und zerstört werden. Ich implementiere IDisposable auch auf allen Repositories / Interfaces, um Ressourcen zu bereinigen.
Ich habe umfangreiche Tests der Anwendung mit Speicherprofilen wie dem ANTS-Profil von Red Gate, WinDbg und anderen durchgeführt und konnte bisher die genaue Ursache des Speicherproblems nicht feststellen, habe jedoch Folgendes notiert:
>Ein Red-Gate-ANTS-Profilertest zeigt, dass zu viele Entitäten vorhanden sind Framework MetadataWorkspaces, die erstellt werden, verursachen viele zusätzliche Objektzuordnungen und zugehöriger SQL-Befehlstext, der gehalten werden soll. Da ist auch einzelne Instanz von myEntities in einem bestimmten Repository, die enthält einen MetadataWorkspace und den InitializerMetadata-Cache enthält 351 Einträge am Ende eines Stresstests. Diese 351 Einträge Jede hat eine andere Kopie von myEntities, jede davon hat eine MetadataWorkspace, und jeder von diesen hat Hunderte von Objektzuordnungen.
Meine Kernlösung ist wie folgt strukturiert:
Wenn jemand irgendwelche Hinweise geben kann, wäre ich sehr dankbar.
Wir gehen automatisch davon aus, dass das Problem der EF ist. Kann sein, kann nicht sein. Es gibt viele Punkte, auf die wir achten sollten, nicht nur die Datenzugriffsinfrastruktur.
Wenn Datenzugriff erteilt wird, können Sie mit der einfachen Methode .AsNoTracking()
eine schnelle Verbesserung erzielen, da Sie nur EF verwenden. Übernehmen Sie einen ServiceLocator , mit dem Sie Ihren Kontexte-Pool verwalten können.
Sie können in ReadOnly-Situationen auch Dapper anstelle von EF verwenden.
Und zu guter letzt, verwenden Sie reines ADO.NET, für die komplexeren Abfragen und eine schnellste Ausführung.
Refrazieren Sie Ihre ActionFilters , um zu vermeiden, dass ein "BaseController", den alle Controller erben, eine gute Methode ist .
Überprüfen Sie, ob Ihre IDisposable-Klassen wirklich von CG unterdrückt werden und das Muster .Dispose(bool)
übernehmen.
Stellen Sie sicher, dass Sie keine Cache-Variablen für die Ewigkeit beibehalten, die nur durch die Wiederverwendung des Anwendungspools freigegeben werden.
Das sind nur Tipps, aber die harte Arbeit wird mit dir sein, die Codezugriff haben. :)
Viel Glück!
Tags und Links asp.net-mvc memory-leaks entity-framework