Übermäßig hohe Speichernutzung in der .NET MVC / Entity Framework-Anwendung

8

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:

  • Präsentation - ASP.NET MVC 3
  • Business - Objekte, ViewModels, Interfaces
  • Infrastruktur - Entity-Framework-Modell
  • Datenzugriff - ADO.NET Direct Data Access

Wenn jemand irgendwelche Hinweise geben kann, wäre ich sehr dankbar.

    
Nick 16.08.2013, 00:57
quelle

2 Antworten

3

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!

    
Thiago Lunardi 31.10.2014, 17:04
quelle
0

Überprüfen Sie, ob Proxy-Entitäten in der Sitzung gespeichert sind. Auf der anderen Seite ist es nicht erforderlich, explizit Dispose() in DbContext aufzurufen. Überprüfen Sie dies Ссылка

    
Perdom 20.02.2015 15:53
quelle