ASP.NET Core核心转储分析结果解读及两类问题排查方法
针对ASP.NET Core转储分析问题的排查方案
问题1:AA0013堆异常无堆栈跟踪的排查
为什么没有堆栈跟踪?
- 异常仅被实例化但从未抛出:这类异常不会生成堆栈信息,只是驻留在堆中。
- 异常被错误重抛:代码中用
throw ex;而非throw;抛出异常,会丢失原始堆栈上下文。 - 转储解析工具限制:Visual Studio的自动分析可能未完整解析异常的
StackTrace属性,换用命令行工具能获取更多细节。 - 转储完整性不足:默认
dotnet-dump collect可能未收集到完整内存页,导致堆栈信息丢失。
进一步排查步骤
- 用
dotnet-dump命令行分析现有转储- 运行
dotnet-dump analyze <你的转储文件路径>进入分析环境 - 执行
dumpheap -type Exception列出堆中所有异常对象,记录异常的内存地址 - 对每个异常地址执行
dumpobj <地址>,查看Message、InnerException属性,以及StackTrace字段的原始数据(即便Visual Studio没显示,命令行可能能解析出来)
- 运行
- 重新收集完整转储
- 若现有转储是轻量版,重新收集时添加
-f参数生成完整转储:dotnet-dump collect -p <PID> -f
- 若现有转储是轻量版,重新收集时添加
- 结合应用日志辅助定位
- 查看生产环境的应用日志、Windows事件日志,寻找与异常类型匹配的报错记录,补充上下文信息
问题2:AA0003终结器队列阻塞的根因定位
核心排查步骤
- 查看终结器队列状态
- 在
dotnet-dump analyze环境中执行!finalizequeue(SOS命令),查看队列中等待终结的对象数量、类型,以及已注册但未执行的终结方法 - 用
dumpheap -type <堆积的对象类型>查看具体对象的引用链,确认哪些对象在队列中积压
- 在
- 检查终结器线程状态
- 执行
threads列出所有线程,找到标记为Finalizer的专属线程 - 对该线程执行
clrstack,查看当前调用栈,确认终结器线程是否卡在某个方法(比如等待锁、网络IO、数据库操作)
- 执行
- 关联内存占用问题
- 用
eeheap -gc查看各代堆的内存占用,确认是否是待终结对象本身(或其引用的大对象)占用了大量内存 - 检查积压对象的类型:如果是数据库连接、文件流、第三方组件对象,重点排查它们的终结方法是否存在阻塞逻辑,或者是否未正确实现
IDisposable导致大量对象进入终结队列
- 用
内容的提问来源于stack exchange,提问作者Robert Hegner
相关产品推荐
相关产品推荐

