0

Ich habe eine vorkompilierte Webanwendung (32 Bit), wo die Speicherauslastung langsam steigt, bis ich OutOfMemoryExceptions bekomme. Mit einem Profiler habe ich festgestellt, dass der Hauptverdächtige Strings in System.Web.VirtualPath-Objekten sind, die wiederum in der Hashtable _localResourcesAssemblies in einem System.Web.Compilation.BuildManager-Objekt gespeichert sind.WebAPI-Speicherverlust in BuildManager

Diese Einträge scheinen in Stapeln von ca. 50 MB alle 4-6 Stunden hinzugefügt zu werden. Ich stehe fest - ich habe keine Ahnung, was in den BuildManager ruft, der diese Einträge hinzufügt. Wenn Sie die Einträge betrachten, enthalten sie Pfade, die mit gültigen Routen eines attributgesteuerten Controllers (oder übergeordneten Pfaden gültiger Routenpfade) übereinstimmen.

Keine Dateien sollten sich im Verzeichnis der Anwendung ändern.

Ich habe eine einfache Web-App mit ähnlichen Routen eingerichtet, um zu sehen, ob ich das Problem reproduzieren kann, aber ich konnte das Problem nicht auf der Test-App reproduzieren.

Irgendwelche Ideen, wie ich finden kann, was ruft in den BuildManager (versiegelte Klasse, wahrscheinlich Singleton) Objekt?

+0

ich eine Lösung haben ... Falls jemand anderes muss, bevor ich es bestätigen kann, ist es scheint der Schuldige ist der WebPages-Teil von ASP.NET. Wir haben nur die Hilfeseite ... der Rest unserer App ist WebAPI. Wir werden die Bereichsregistrierung auskommentieren und sehen, ob das Dinge behebt. – cgroneman

Antwort

0

Umgehung: die Microsoft.AspNet.WebPages entfernen nuget Paket (und Seiten, die davon abhängen, einschließlich dem Microsoft.AspNet.WebApi.HelpPage Paket).

Wir haben schließlich einen Stack-Trace mit dem Out of Memory von der wahren Ursache des Problems (die meisten unserer Spuren waren in unserem eigenen Code, wo wir mehrere MB auf einmal zuordnen). Stack-Trace wird unten veröffentlicht.

Wir konnten feststellen, dass das WebPages-HTTP-Modul dynamisch hinzugefügt wird und den Callback registriert, der jeden URL-Pfad zu einem Cache in BuildManager hinzufügt, und dies aufgrund unseres 32-Bit-Speicherplatzes und einer großen Anzahl eindeutiger Pfade führt uns schließlich aus dem Speicher.

Wie versprochen, die Stacktrace, die schließlich in der Lage war, uns auf die Ursache des Problems zu führen:

Exception type: OutOfMemoryException 
Exception message: Exception of type 'System.OutOfMemoryException' was thrown. 
at System.Collections.Hashtable.rehash(Int32 newsize, Boolean forceNewHashCode) 
at System.Collections.Hashtable.expand() 
at System.Collections.Hashtable.Insert(Object key, Object nvalue, Boolean add) 
at System.Collections.Hashtable.set_Item(Object key, Object value) 
at System.Web.Compilation.BuildManager.EnsureFirstTimeDirectoryInit(VirtualPath virtualDir) 
at System.Web.Compilation.BuildManager.GetBuildResultFromCacheInternal(String cacheKey, Boolean keyFromVPP, VirtualPath virtualPath, Int64 hashCode, Boolean ensureIsUpToDate) 
at System.Web.Compilation.BuildManager.GetVPathBuildResultFromCacheInternal(VirtualPath virtualPath, Boolean ensureIsUpToDate) 
at System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate) 
at System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate) 
at System.Web.Compilation.BuildManager.GetVirtualPathObjectFactory(VirtualPath virtualPath, HttpContext context, Boolean allowCrossApp, Boolean throwIfNotFound) 
at System.Web.Compilation.BuildManager.GetObjectFactory(String virtualPath, Boolean throwIfNotFound) 
at System.Web.WebPages.BuildManagerWrapper.GetObjectFactory(String virtualPath) 
at System.Web.WebPages.BuildManagerWrapper.ExistsInPrecompiledSite(String virtualPath) 
at System.Web.WebPages.BuildManagerWrapper.Exists(String virtualPath) 
at System.Web.WebPages.VirtualPathFactoryManager.Exists(String virtualPath) 
at System.Web.WebPages.DefaultDisplayMode.GetDisplayInfo(HttpContextBase httpContext, String virtualPath, Func`2 virtualPathExists) 
at System.Web.WebPages.DisplayModeProvider.GetDisplayInfoForVirtualPath(String virtualPath, HttpContextBase httpContext, Func`2 virtualPathExists, IDisplayMode currentDisplayMode, Boolean requireConsistentDisplayMode) 
at System.Web.WebPages.DisplayModeProvider.GetDisplayInfoForVirtualPath(String virtualPath, HttpContextBase httpContext, Func`2 virtualPathExists, IDisplayMode currentDisplayMode) 
at System.Web.WebPages.WebPageRoute.GetRouteLevelMatch(String pathValue, String[] supportedExtensions, Func`2 virtualPathExists, HttpContextBase context, DisplayModeProvider displayModeProvider) 
at System.Web.WebPages.WebPageRoute.MatchDefaultFiles(String pathValue, String[] supportedExtensions, Func`2 virtualPathExists, HttpContextBase context, DisplayModeProvider displayModes, String currentLevel) 
at System.Web.WebPages.WebPageRoute.MatchRequest(String pathValue, String[] supportedExtensions, Func`2 virtualPathExists, HttpContextBase context, DisplayModeProvider displayModes) 
at System.Web.WebPages.WebPageRoute.DoPostResolveRequestCache(HttpContextBase context) 
at System.Web.WebPages.WebPageHttpModule.OnApplicationPostResolveRequestCache(Object sender, EventArgs e) 
at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)