You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.Net Core应用部件程序集无法卸载问题排查求助

排查可回收加载上下文无法卸载的残留引用

针对你遇到的应用部件卸载后Collectible AssemblyLoadContext无法正常卸载的问题,以下是几个重点排查方向:

1. 检查ActionDescriptor及路由相关的残留引用

虽然ActionDescriptionCollection已更新,但路由系统或Action处理链中可能存在旧对象的缓存:

  • 查看EndpointDataSource(尤其是MvcEndpointDataSource)的实例,确认来自目标程序集的Endpoint是否已被完全移除。部分路由缓存可能不会自动刷新,需手动触发路由重建。
  • 检查自定义筛选器、模型绑定器或视图组件是否持有旧ActionDescriptor的引用,这类组件常被缓存到Mvc系统的内部集合中。

2. DI容器中的服务残留

如果目标程序集的类型被注册到DI容器:

  • 排查Singleton服务:Singleton实例会一直存活到应用终止,若持有程序集类型引用,会直接阻止加载上下文卸载。需确认是否有未清理的Singleton注册或实例。
  • 检查Scoped服务:若存在未释放的Scoped服务实例(比如当前请求未结束,或某个Scoped服务被意外提升为Singleton),也会残留引用。

3. 应用部件Feature的缓存

ApplicationPartManager的FeatureProviders生成的Feature集合可能被其他服务缓存:

  • 获取ControllerFeature、ViewComponentFeature等实例,确认其中是否还包含目标程序集的类型。部分内部服务(如IMvcFeatureProviderCache)可能缓存旧的Feature数据。
  • 尝试手动调用ApplicationPartManager.PopulateFeature<TFeature>刷新Feature,再检查加载上下文状态。

4. 深入Windbg分析

用Windbg做更精准的根引用查找:

  1. 找到目标程序集的对象地址:
    !dumpheap -type Assembly
    
  2. 针对该地址查找所有根引用:
    !gcroot <assembly-address>
    
    注意排查弱引用队列、终结器队列中的引用,以及加载上下文自身的关联对象。
  3. 查看加载上下文状态:
    !dumpdomain
    
    找到对应的Collectible AssemblyLoadContext,检查IsUnloaded属性,以及关联模块的引用计数。

5. 静态引用与JIT代码

  • 检查目标程序集是否有静态字段、静态构造函数持有外部引用,或被其他静态类引用。静态引用会绕过GC回收,阻止加载上下文卸载。
  • 若程序集类型被JIT编译,可尝试使用!dumpmodule <module-address>查看模块的引用计数,确认是否有本机代码层面的残留引用。

6. 自定义变更通知组件的问题

检查你的CustomActionDescriptorChangeProvider:

  • 是否所有依赖该Provider的服务都正确响应了变更?比如某些自定义缓存服务可能未监听变更事件,导致旧数据残留。
  • 确认TokenSource.Cancel()后,所有关联的CancellationToken是否已正确传递到相关服务,触发缓存清理。

内容的提问来源于stack exchange,提问作者Georgi Yankov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 04:27:31