在 Azure Web 应用程序上调试内存泄漏:内存分析失败
Debugging Memory Leak on Azure Web App: Memory Analysis Fails
我正在尝试诊断 Azure Web 应用程序上的内存泄漏。
我使用诊断和解决问题 > 诊断工具 > 收集内存转储(参考工具 )。
这会收集一个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 apps使用的分析工具可以在https://www.microsoft.com/en-us/download/confirmation.aspx?id=58210
下载
但这并没有解决我的问题。我仍然遇到内存不足异常。
我监控了系统内存使用情况,它从未接近用完。
在 Program Files\DebugDiag\AnalysisRules\DebugDiag.AnalysisRules.dll.config
中增加了 GCRootTimeout。
我还在我能找到的每个配置文件中设置了 gcAllowVeryLargeObjects。
感谢您分享您的转储文件@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.dllE7D1ED77b0000\SOS_x86_x86_4.8.4180.00.dll
SYMSRV: RESULT: 0x00000000
DBGHELP: C:\debug\sym\SOS_x86_x86_4.8.4180.00.dllE7D1ED77b0000\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 and run !mex.dumpheap2
or use PerfView分析堆。
Mex 显示了相当数量的 Automapper objects
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 打开转储和转储 GC 堆,我们可以获得更好的画面
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 blade 中将您的 Web 应用程序从 x86 更改为 x64,这至少会给您一些喘息的空间。重新启动您的应用程序后,从 诊断和解决问题 blade 收集内存转储以获得基线。然后配置 AutoHeal 以在内存达到上限阈值时收集转储文件,以绕过 运行 遇到的 OOM。此外,Perfview 将允许您与转储堆进行比较,以便您可以看到哪些 objects 在分配中增长;查看在 Perfview 中启动分析帮助以获取更多信息。
根据我的个人经验,如果配置不当,AutoMapper 可能会导致性能问题。我曾经在每次处理不需要的数据时创建一个映射器。看起来您还向 AutoFac IoC 容器添加了一个映射器,并且该映射器引用了一个 EventHandler。事件处理程序可以将 objects 固定到堆上,防止 GC 收集它。
我正在尝试诊断 Azure Web 应用程序上的内存泄漏。
我使用诊断和解决问题 > 诊断工具 > 收集内存转储(参考工具
这会收集一个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 apps使用的分析工具可以在https://www.microsoft.com/en-us/download/confirmation.aspx?id=58210
下载但这并没有解决我的问题。我仍然遇到内存不足异常。
我监控了系统内存使用情况,它从未接近用完。
在 Program Files\DebugDiag\AnalysisRules\DebugDiag.AnalysisRules.dll.config
中增加了 GCRootTimeout。
我还在我能找到的每个配置文件中设置了 gcAllowVeryLargeObjects。
感谢您分享您的转储文件@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.dllE7D1ED77b0000\SOS_x86_x86_4.8.4180.00.dll
SYMSRV: RESULT: 0x00000000
DBGHELP: C:\debug\sym\SOS_x86_x86_4.8.4180.00.dllE7D1ED77b0000\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 and run !mex.dumpheap2
or use PerfView分析堆。
Mex 显示了相当数量的 Automapper objects
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 打开转储和转储 GC 堆,我们可以获得更好的画面
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 blade 中将您的 Web 应用程序从 x86 更改为 x64,这至少会给您一些喘息的空间。重新启动您的应用程序后,从 诊断和解决问题 blade 收集内存转储以获得基线。然后配置 AutoHeal 以在内存达到上限阈值时收集转储文件,以绕过 运行 遇到的 OOM。此外,Perfview 将允许您与转储堆进行比较,以便您可以看到哪些 objects 在分配中增长;查看在 Perfview 中启动分析帮助以获取更多信息。
根据我的个人经验,如果配置不当,AutoMapper 可能会导致性能问题。我曾经在每次处理不需要的数据时创建一个映射器。看起来您还向 AutoFac IoC 容器添加了一个映射器,并且该映射器引用了一个 EventHandler。事件处理程序可以将 objects 固定到堆上,防止 GC 收集它。