【问题标题】:Debugging Memory Leak on Azure Web App: Memory Analysis Fails在 Azure Web App 上调试内存泄漏:内存分析失败
【发布时间】:2020-10-06 15:17:33
【问题描述】:

我正在尝试诊断 Azure Web App 上的内存泄漏。

我使用诊断和解决问题 > 诊断工具 > 收集内存转储(工具引用 here)。

这会收集 dmp 文件并生成分析报告。我可以在 Crash Hang Analysis 中看到线程和其他信息,但 DotNetMemoryAnaysis 总是失败并出现错误

Type:  System.OutOfMemoryException

Message:  Exception of type 'System.OutOfMemoryException' was thrown.

Stack Trace:
DebugDiag.DotNet.NetDbgObj.d__73.MoveNext()
System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()
System.Linq.Lookup`2.Create[TSource](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
System.Linq.GroupedEnumerable`3.GetEnumerator()
System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
System.Linq.Buffer`1..ctor(IEnumerable`1 source)
System.Linq.OrderedEnumerable`1.d__1.MoveNext()
System.Linq.Enumerable.d__25`1.MoveNext()
System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
DebugDiag.AnalysisRules.DotNetMemoryAnalysis.GCRootWalker.ShowRoots(NetScriptManager manager, NetDbgObj debugger, NetProgress progress, IEnumerable`1 top40Query) in C:\src\DebugDiag\Development\src\DebugDiag.AnalysisRules\DotNetMemoryAnalysis.cs:line 1875
DebugDiag.AnalysisRules.DotNetMemoryAnalysis.DoDotNetMemoryAnalysis() in C:\src\DebugDiag\Development\src\DebugDiag.AnalysisRules\DotNetMemoryAnalysis.cs:line 222
DebugDiag.AnalysisRules.DotNetMemoryAnalysis.RunAnalysisRule(NetScriptManager manager, NetProgress progress) in C:\src\DebugDiag\Development\src\DebugDiag.AnalysisRules\DotNetMemoryAnalysis.cs:line 182
DebugDiag.DotNet.NetAnalyzer.RunAnalysisRulesInternal(DumpFileType bitness, NetProgress progress, String symbolPath, String imagePath, String reportFileFullPath, Boolean twoTabs, AnalysisModes analysisMode)

我尝试使用dotnet-dump cli 工具分析文件,但任何分析操作都会出错 SOS does not support the current target architecture 0x0000014c。 在 Visual Studio 中打开 dmp 似乎也没有提供任何分析选项,只是调试。

有没有办法从另一台机器上运行 dmp 分析?我应该以其他方式收集转储吗?

更新

windows上azure web应用使用的分析工具可以在https://www.microsoft.com/en-us/download/confirmation.aspx?id=58210下载

但这并没有解决我的问题。我仍然遇到内存不足异常。

我监控了系统内存使用情况,但它从未接近过满。

Program Files\DebugDiag\AnalysisRules\DebugDiag.AnalysisRules.dll.config 中的 GCRootTimeout 增加。

我还在我能找到的每个配置文件中设置了gcAllowVeryLargeObjects

【问题讨论】:

  • 我只是想确认您在应用服务计划中运行的是 S1 或更高版本的 SKU?您的应用是 .NETCORE 还是 .NETFX?版本?如果您有转储文件,您是否尝试过使用WinDb?应用名称是什么?要私下分享,请将其发送至 AzCommunity[at]microsoft[dot]com ATTN Ryan,我会看看。
  • 谢谢瑞恩。我的应用服务计划是运行 .Net Framework 4.8 Asp.NET MVC 5 站点的 P1V2。我还没有尝试过 WindDbg。我现在已经在 WinDbg 中加载了 dmp,但是如何获取我需要的信息并不明显。我需要进行一些研究和实验。我会尽快将具体的站点详细信息发送到电子邮件中。再次感谢!
  • 您需要从.loadby sos clr 开始加载SOS extensions,这样您就可以使用!dumpobj 命令。这将按实例计数和大小列出 dmp 文件中的对象。如果您在使用 .loadby 时遇到问题,请告诉我。

标签: .net memory-leaks azure-web-app-service .net-framework-4.8


【解决方案1】:

感谢@farlee2121 分享您的转储文件。我使用WinDbg 打开了您的转储文件并启动了!analyze -v。这会将可用符号提取到您的本地缓存中。

SYMSRV:  BYINDEX: 0x1D
         https://msdl.microsoft.com/download/symbols
         SOS_x86_x86_4.8.4180.00.dll
         5E7D1ED77b0000
SYMSRV:  PATH: C:\debug\sym\SOS_x86_x86_4.8.4180.00.dll\5E7D1ED77b0000\SOS_x86_x86_4.8.4180.00.dll
SYMSRV:  RESULT: 0x00000000
DBGHELP: C:\debug\sym\SOS_x86_x86_4.8.4180.00.dll\5E7D1ED77b0000\SOS_x86_x86_4.8.4180.00.dll - OK

当尝试查看堆时,!dumpheap -stat 导致...

Object <exec cmd="!ListNearObj /d 5cdcf038">5cdcf038</exec> has an invalid method table.
0:000> !ListNearObj /d 5cdcf038
Before:  5cdcf014           36 (0x24)   System.Collections.Hashtable+HashtableEnumerator
After:  couldn't find any object between 0x5cdcf038 and 0x5cdd00cc
Heap local consistency not confirmed.

...这可能表明 GC 可能在收集转储时正在运行。在这一点上,我们可以做两个选择。一种是使用mex extension 并运行!mex.dumpheap2 或使用PerfView 来分析堆。

Mex 展示了大量 Automapper 对象

1,014,591 20,291,820 System.Linq.Expressions.FullConditionalExpression
2,873     24,391,820 System.Char[]
1,541,328 24,661,248 System.Linq.Expressions.AssignBinaryExpression
1,680,035 26,880,560 AutoMapper.Mappers.ConvertMapper+<>c__DisplayClass1_1
1,571,447 31,428,940 System.Linq.Expressions.LogicalBinaryExpression
1,680,036 33,600,720 System.Lazy<System.Linq.Expressions.LambdaExpression>
1,194,017 33,941,972 System.Linq.Expressions.Expression[]
3,161,253 37,935,036 System.Linq.Expressions.ConstantExpression
9,941     39,286,832 System.Collections.Generic.Dictionary+Entry<AutoMapper.TypePair,System.Lazy<System.Linq.Expressions.LambdaExpression>>[]
844,692   39,384,092 System.Reflection.MemberInfo[]
665,549   47,919,528 AutoMapper.PropertyMap
1,680,036 53,761,152 System.Func<System.Linq.Expressions.LambdaExpression>
253,050   58,765,632 System.Int32[]
339,941   61,674,100 System.String
25,206    70,703,012 System.Byte[]
Total 37,374,335 Object(s), Total Size: 1.03 GB, Free Objects 812(352.21 KB)

如果你使用Perfview打开dump和Dump GC Heap,我们可以得到更好的画面

Name                                                                                                                                        Inc %              Inc
 LIB <<System.Core!Linq.Expressions.Expression>>>                                                                                            21.8      214,783,296
+ AutoMapper!AutoMapper.TypeMap                                                                                                              21.8      214,783,296
 + LIB <<mscorlib!Dictionary>>                                                                                                               21.8      214,783,296
 |+ AutoMapper!AutoMapper.MapperConfiguration                                                                                                21.8      214,783,296
 ||+ AutoMapper!AutoMapper.Mapper                                                                                                            21.8      214,783,296
 |||+ Fourstarzz.Accessors!Fourstarzz.Accessors.EntityFramework.DtoMapper                                                                    21.8      214,783,296
 ||||+ Fourstarzz.Accessors!Fourstarzz.Accessors.IntegrationAccessInfoAccessor                                                               21.8      214,783,296
 |||||+ Fourstarzz.Managers!Fourstarzz.Managers.Identity.AccountConnectionManager                                                            10.9      108,058,320
 ||||||+ Fourstarzz.Managers.Adapters!Fourstarzz.Managers.Adapters.Identity.OkanjoRegistrationHandler                                        10.9      108,058,320
 |||||| + Fourstarzz.Managers.Adapters!Fourstarzz.Managers.Adapters.Identity.CompositeIdentityEventHandler                                   10.9      108,058,320
 ||||||  + Fourstarzz.Managers!Fourstarzz.Managers.Identity.UserIdentityManager                                                              10.9      108,058,320
 ||||||   + Fourstarzz.Clients.Website!Fourstarzz.Clients.Website.IdentityWrapper                                                            10.9      108,058,320
 ||||||   |+ LIB <<System!Stack<Object>>>                                                                                                    10.9      108,058,320
 ||||||   | + Autofac!Autofac.Core.Disposer                                                                                                  10.9      108,058,320
 ||||||   |  + Autofac!Autofac.Core.Lifetime.LifetimeScope                                                                                   10.9      108,058,320
 ||||||   |  |+ LIB <<mscorlib!Func>>                                                                                                        10.9      108,058,320
 ||||||   |  | + Microsoft.AspNet.Identity.Owin!Owin.AppBuilderExtensions+<>c__DisplayClass1                                                 10.9      108,058,320
 ||||||   |  | |+ LIB <<mscorlib!Func,Microsoft.Owin.IOwinContext,Fourstarzz.Shared.FourstarzzIdentity.FourstarzzUserManager>>>              10.9      108,058,320
 ||||||   |  | ||+ Microsoft.AspNet.Identity.Owin!Microsoft.AspNet.Identity.Owin.IdentityFactoryProvider                                     10.9      108,058,320
 ||||||   |  | || + Microsoft.AspNet.Identity.Owin!Microsoft.AspNet.Identity.Owin.IdentityFactoryOptions                                     10.9      108,058,320
 ||||||   |  | ||  + Microsoft.AspNet.Identity.Owin!Microsoft.AspNet.Identity.Owin.IdentityFactoryMiddleware>                                10.9      108,058,320
 ||||||   |  | ||   + Microsoft.AspNet.Identity.Owin!Microsoft.AspNet.Identity.Owin.IdentityFactoryMiddleware>                               10.9      108,058,320
 ||||||   |  | ||    + Microsoft.Owin!Microsoft.Owin.Infrastructure.OwinMiddlewareTransition                                                 10.9      108,058,320
 ||||||   |  | ||     + LIB <<Microsoft.Owin.Host.SystemWeb!Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineBlueprint>>   10.9      108,058,320
 ||||||   |  | ||      + [static var Microsoft.Owin.Host.SystemWeb.OwinHttpModule._blueprint]                                                10.9      108,058,320
 ||||||   |  | ||       + [static vars]                                                                                                      10.9      108,058,320

这里有一些事情要进一步进行。首先,在 Application Settings 刀片上将您的 Web 应用程序从 x86 更改为 x64,这至少会给您一些喘息的空间。重新启动您的应用程序后,从 诊断和解决问题 刀片收集内存转储以获取基线。然后配置AutoHeal 以在内存达到上限阈值时收集转储文件以绕过您遇到的OOM。此外,Perfview 将允许您与转储堆进行比较,以便查看哪些对象在分配中增长;查看在 Perfview 中启动分析帮助以获取更多信息。

根据我的个人经验,如果配置不当,AutoMapper 可能会导致性能问题。每次我在不需要时处理数据时,我都会创建一个 Mapper。看起来您向 AutoFac IoC 容器添加了一个映射器,并且该映射器具有对 EventHandler 的引用。事件处理程序可以将对象固定到堆上,防止 GC 收集它。

【讨论】:

  • 这真的很有帮助!我四处寻找,并没有在任何地方通过 AutoFac 显式绑定 AutoMapper。我尽量把它作为课堂的内部细节。不过,我确实有一些映射器的静态缓存。这也会导致它被固定。
  • 自动治疗很隐蔽,但它包含了很多可能性
猜你喜欢
  • 2016-07-02
  • 2013-05-24
  • 1970-01-01
  • 1970-01-01
  • 2023-03-21
  • 2010-12-01
  • 2012-05-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多